PHP桥接模式

阅读目录

项目目录结构

    目录: D:\bridge


Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a----         2021/9/16     10:19            276 EatByChopsticks.php
-a----         2021/9/16     10:19            270 EatByFork.php
-a----         2021/9/16     10:19            200 EatInterface.php
-a----         2021/9/16     10:19            654 PersonAbstract.php
-a----         2021/9/16     10:19            276 PersonMale.php
-a----         2021/9/16     10:19            962 test.php

吃接口

<?php
namespace bridge;

# 吃接口
interface EatInterface
{
  # 吃 @param  string $food 食物
  public function eat($food='');
}

用筷子吃实体

<?php
namespace bridge;

# 用筷子吃实体
class EatByChopsticks implements EatInterface
{
  # 吃 @param  string $food 食物
  public function eat($food='')
  {
    echo "用筷子吃{$food}~";
  }
}

用叉子吃实体

<?php
namespace bridge;

# 用叉子吃实体
class EatByFork implements EatInterface
{
  # 吃
  public function eat($food='')
  {
    echo "用叉子吃{$food}~";
  }
}

人抽象类

<?php
namespace bridge;

# 人抽象类
abstract class PersonAbstract
{
  # 性别
  protected $_gender = '';

  # 使用的吃饭工具
  protected $_tool   = '';

  # 构造函数 @param string       $gender 性别
  public function __construct($gender='',EatInterface $tool)
  {
    $this->_gender = $gender;
    $this->_tool   = $tool;
  }

  # 吃的行为  @param  string $food 实物
  abstract public function eat($food='');
}

男人实类

<?php
namespace bridge;

# 男人实类
class PersonMale extends PersonAbstract
{
  # 吃的具体方式 @param  string $food 食物
  public function eat($food='')
  {
    $this->_tool->eat($food);
  }
}

运行示例

结构型模式

  • php桥接模式
  • 基础的结构型设计模式:将抽象和实现解耦,对抽象的实现是实体行为对接口的实现
  • 例如:人 => 抽象为属性:性别 动作:吃 => 人吃的动作抽象为interface => 实现不同的吃法

运行 php test.php

// 注册自加载
spl_autoload_register('autoload');

function autoload($class)
{
  require dirname($_SERVER['SCRIPT_FILENAME']).'//..//'.str_replace('\\','/',$class).'.php';
}

/************************************* test *************************************/

use bridge\PersonMale;
use bridge\EatByChopsticks;
use bridge\EatByFork;

try {
  // 初始化一个用筷子吃饭的男人的实例
  $male = new PersonMale('male', new EatByChopsticks());
  // 吃饭
  $male->eat('大盘鸡');

} catch (\Exception $e) {
  echo $e->getMessage();
}
php test.php
用筷子吃大盘鸡~
try {
  // 初始化一个用筷子吃饭的男人的实例
  $male = new PersonMale('male', new EatByFork());
  // 吃饭
  $male->eat('大盘鸡');

} catch (\Exception $e) {
  echo $e->getMessage();
}
用叉子吃大盘鸡~

知识点

PHP interfase 对象接口

1 、使用接口(interface),可以指定某个类必须实现哪些方法,但不需要定义这些方法的具体内容。

2、接口是通过 interface 关键字来定义的,就像定义一个标准的类一样,但其中定义所有的方法都是空的。

3、 接口中定义的所有方法都必须是公有,这是接口的特性。

需要注意的是:

在接口中定义一个构造方法是被允许的。在有些场景下这可能会很有用,例如用于工厂模式时。

实现一个接口,使用 implements 操作符

1、类中必须实现接口中定义的所有方法,否则会报一个致命错误。

2、类可以实现多个接口,用逗号来分隔多个接口的名称。

注意:
接口也可以继承,通过使用 extends 操作符。
类要实现接口,必须使用和接口中所有定义的方法完全一致的方式。否则会导致致命错误。

PHP接口和常量

接口中也可以定义常量。
接口中常量和类常量的使用完全相同,但是不能被子类或子接口所覆盖。

尽管不能再接口中包含变量,但是可以包含常量。要使用常量,需要用到 “作用域解析操作符” 即是双冒号::

示例:使用接口常量的一般格式

$someVariable = InterfaceName::SOME_CONSTANT;

演示

接口文件 IConnectInfo.php

<?php
interface IConnectInfo
{
	// 定义常量
    const HOST = "localhost";
    const UNAME = "root";
    const DBNAME = "wqzbxh";
    const PW = "root";
    function testConnection();
}

使用接口文件 ConSQL.php

<?php
//引入IConnectInfo接口
include_once('IConnectInfo.php');

Class ConSQL implements IConnectInfo
{
    private $server = IConnectInfo::HOST;
    private $currenDB = IConnectInfo::DBNAME;
    private $user = IConnectInfo::UNAME;
    private $password = IConnectInfo::PW;

    public function testConnection()
    {
        // TODO: Implement testConnection() method.
        try{
            $hookup = new mysqli($this->server,$this->user,$this->password,$this->currenDB);
            if(mysqli_connect_errno()){
                die('connection fail!');
            }
            echo "You are hooked Up Ace!<br/>".$hookup->host_info;
            $hookup->close();
        }catch (Exception $e){
            echo $e->getMessage();
        }
    }
}
$useConstant = new ConSQL();
$useConstant->testConnection();
php .\ConSQL.php
You are hooked Up Ace!<br/>localhost via TCP/IP

这里面接口文件只有一个testconnection方法,但是如果愿意接口中也可以只包含变量不包含任何方法。

PHP 5 支持抽象类和抽象方法

定义为抽象的类不能被实例化。

任何一个类,如果里面有一个方法是被声明为抽象的,那么这个类就必须被声明为抽象的。
被定义为抽象的方法只是声明了其调用方式(参数),不能定义其具体的功能实现。

继承一个抽象类的时候,子类必须定义父类中的所有抽象方法;

另外,这些方法的访问控制必须和父类中一样(或者更为宽松)。

例如某个抽象方法被声明为受保护的,
那么子类中实现的方法就应该声明为受保护的或者公有的,而不能定义为私有的。
此外方法的调用方式必须匹配,即类型和所需参数数量必须一致。

<?php
abstract class AbstractClass
{
    //强制要求子类定义这些方法
    abstract protected function getValue();
    abstract protected function prefixValue($prefix);

    //普通方法非抽象方法
    public function printout(){
        print $this->getValue()."\n";
    }
}
class ChildAbstract extends AbstractClass{
    protected function getValue(){
        return "ChildAbstract";
    }
    public function prefixValue($prefix){
        return $prefix."ChildAbstract";
    }
}

$class1 = new ChildAbstract;
$class1->printout();
echo PHP_EOL.$class1->prefixValue('FOO_');
/*运行结果
ChildAbstract
FOO_ChildAbstract
*/
上一篇:【无标题】


下一篇:命名习惯建议