PHP行为型设计模式(四)

续上一篇:PHP行为型设计模式(三),本文介绍第四类行为型设计模式。

通过中间类

  • 访问者模式(Visitor Pattern)
  • 中介者模式 ( Mediator Pattern)
  • 解释器模式(Interpreter Pattern)

PHP设计模式(二十)—访问者模式(Visitor Pattern)

访问者模式(Visitor Pattern) : 表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素类的前提下定义作用于这些元素的新操作。

(一)为什么需要访问者模式

访问者模式能够在不更改对象的情况下向该对象添加新的功能性

(二)访问者模式 UML图

Visitor Pattern

访问者模式UML图通常是比较复杂,如果对于只有一个元素和一种访问者,我们其实也可以不用抽象元素和抽象访问者,不要objectStruct
下图给出《PHP设计模式》中的访问者模式UML图。

Visitor Pattern

(三)简单实例

由于访问者模式的复杂,可能一开始大家看了好久也不知其所然。我也是看了好久都不知道访问者模式的意思。所以这里我只用《PHP设计模式》一书中的UML图,实现如何在不更改对象的情况下向该对象添加新的功能性。

<?php
//具体元素
class Superman{
    public $name;
    public function doSomething(){
        echo '我是超人,我会飞'.PHP_EOL;
    }
    public function accept(Visitor $visitor){
        $visitor->doSomething($this);
    }
}
//具体访问者
class Visitor{
    public function doSomething($object){
        echo '我可以返老还童到'.$object->age = 18;
    }
}
//实例化具体对象
$man = new Superman;
//使用自己的能力
$man->doSomething();
//通过添加访问者,把访问者能能力扩展成自己的
$man->accept(new Visitor);复制代码

我们可以看到,通过调用accept方法接收一个访问者,具体对象可以把访问者的doSomething能力也扩展为自己能力。当然如果你需要多个扩展能力,你可以有多个访问者。而accept方法调用访问者的dosomething方法时,传入$this是为了能使用Superman的属性和方法,使其感觉扩展完就是Superman的真正一部分。


PHP设计模式(二十一)—中介者模式(Mediator Pattern)

中介者模式(Mediator Pattern): 用一个中介对象来封装一系列的对象交互,中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。中介者模式又称为调停者模式,它是一种对象行为型模式。

(一)为什么需要中介者模式

1,中介者模式可以使对象之间的关系数量急剧减少。

2,中转作用(结构性):通过中介者提供的中转作用,各个同事对象就不再需要显式引用其他同事,当需要和其他同事进行通信时,通过中介者即可。该中转作用属于中介者在结构上的支持。

3,协调作用(行为性):中介者可以更进一步的对同事之间的关系进行封装,同事可以一致地和中介者进行交互,而不需要指明中介者需要具体怎么做,中介者根据封装在自身内部的协调逻辑,对同事的请求进行进一步处理,将同事成员之间的关系行为进行分离和封装。该协调作用属于中介者在行为上的支持。

(二)中介者模式 UML图

Mediator Pattern

(三)简单实例

中介者模式的思想在现实生活中也很常见,比如说交换机。没有交换机存在的时代,每个电话之间都需要电话线连接才能进行通话。如果一个台电话要和其它100台电话通话,那么它就必须要有100条电话线与其它100个电话连接。

后来为了解决这种麻烦,交换机出现了。每个电话只需连入交换机,通话时。只需构建一条电话-交换机-电话的链路,就可以进行通话。所以现在我们的电话理论上可以同世界上任何一台电话通话,但是只需一条电话线。当然现在用电话的人少了,但是手机呀,计算机网络的实现也是在传统通信网的设计上进行演进的。

其实交换机对应的就是中介者模式的中介者,而电话机就是中介者中的同事。下面,就让我们用代码来实现这个思想。

<?php
//抽象同事类 --------电话机
abstract class Colleague{
    protected $mediator;    //用于存放中介者
    abstract public function sendMsg($num,$msg);
    abstract public function receiveMsg($msg);
    //设置中介者
    final public function setMediator(Mediator $mediator){
      $this->mediator = $mediator;
    }
}
//具体同事类 ---------座机
class Phone extends Colleague
{
    public function sendMsg($num,$msg)
    {
      echo __class__.'--发送声音:'.$msg.PHP_EOL;
      $this->mediator->opreation($num,$msg);
    }

    public function receiveMsg($msg)
    {
      echo __class__.'--接收声音:'.$msg.PHP_EOL;
    }
}
//具体同事类----------手机
class Telephone extends Colleague
{
    public function sendMsg($num,$msg)
    {
        echo __class__.'--发送声音:'.$msg.PHP_EOL;
        $this->mediator->opreation($num,$msg);
    }
    //手机接收信息前 会智能响铃
    public function receiveMsg($msg)
    {   
        echo '响铃-------'.PHP_EOL;
        echo __class__.'--接收声音:'.$msg.PHP_EOL;
    }
}
//抽象中介者类
abstract class Mediator{
  abstract public function opreation($id,$message);
  abstract public function register($id,Colleague $colleague);
}
//具体中介者类------交换机
class switches extends Mediator
{
    protected  $colleagues = array();
    //交换机业务处理
    public function opreation($num,$message)
    {
        if (!array_key_exists($num,$this->colleagues)) {
            echo __class__.'--交换机内没有此号码信息,无法通话'.PHP_EOL;
        }else{
            $this->colleagues[$num]->receiveMsg($message);
        }
    }
    //注册号码
    public function register($num,Colleague $colleague)
    {
      if (!in_array($colleague, $this->colleagues)) {
          $this->colleagues[$num] = $colleague;
      }
      $colleague->setMediator($this);
    }
}
//实例化固话
$phone = new Phone;
//实例化手机
$telephone = new Telephone;
//实例化交换机
$switches = new Switches;
//注册号码  ---放号
$switches->register(6686668,$phone);
$switches->register(18813290000,$telephone);
//通话
$phone->sendMsg(18813290000,'hello world');
$telephone->sendMsg(6686668,'请说普通话');
$telephone->sendMsg(6686660,'你好');复制代码

PHP设计模式(二十二)—中介者模式(Mediator Pattern)

解释器模式(Interpreter Pattern): 提供了评估语言的语法或表达式的方式,它属于行为型模式。这种模式实现了一个表达式接口,该接口解释一个特定的上下文。这种模式被用在 SQL 解析、符号处理引擎等
(一)为什么需要解释器模式

可以将一个需要解释执行的语言中的句子表示为一个抽象语法树

(二)解释器模式UML图

Interpreter Pattern

(三)简单实例

解释器模式是开发中最少使用的,因为我们亲自编写语法解析的时候总是非常非常少。而且我能想到的解释器模式例子,几乎都是代码繁多到我自己怕,关键是我自己也对这模式有点懵。所以这里我只给出解释器模式的UML图通用代码。

<?php
//抽象表达式 
abstract class Expression{
    //任何表达式子类都应该有一种解析任务
    abstract public function interpreter($context);
}
//抽象表达式是生成语法集合(语法树)的关键,每个语法集合完成指定语法解析任务
//抽象表达式通过递归调用的方法,最终由最小语法单元进行解析完成

//终结符表达式    通常指运算变量
class TerminalExpression extends Expression{
    //终结符表达式通常只有一个
    public function interpreter($context){
        return null; //视具体业务实现
    }
}
//非终结符表达式   通常指运算的符号
class NonterminalExpression extends Expression{
    public function interpreter($context){
        return null;
    }
}复制代码

上一篇::PHP行为型设计模式(三)

感谢阅读,由于笔者也是初学设计模式,能力有限,文章不可避免地有失偏颇
后续更新 PHP设计模式(杂项)介绍,欢迎大家评论指正


我最近的学习总结:


欢迎大家关注我的微信公众号 火风鼎

转载于:https://juejin.im/post/592431c0570c350069cdd3ff

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值