PHP设计模式之中介者模式

上回说道,咱们在外打工的常常会和一类人有很深的接触,那就是房产中介。大学毕业后立刻就能在喜欢的城市买到房子的X二代不在咱们的考虑范围内哈。既然须要长期的租房,那么由于工做或者生活的变更,不可避免的一两年或者三五年就要和房产中介打一次交道。有的时候,咱们租房并不必定会知道房主的信息,房主也不用知道咱们的信息,所有都由中介来进行处理。在这里,中介就成为了咱们沟通的桥梁,这种状况其实就像是房主出国了或者在外地有事儿而将房子彻底的托管到了中介手中。相似于这种状况,在代码世界中,就是中介者模式的典型应用。php

Gof类图及解释

GoF定义:用一个中介对象来封装一系列的对象交互。 中介者使各对象不须要显式地相互引用,从而使其耦合松散,并且能够独立地改变它们之间的交互git

GoF类图github

中介者模式

代码实现web

abstract class Mediator
{
    abstract public function Send(String $message, Colleague $colleague);
}

class ConcreteMediator extends Mediator
{
    public $colleague1;
    public $colleague2;

    public function Send(String $message, Colleague $colleague)
    {
        if ($colleague == $this->colleague1) {
            $this->colleague2->Notify($message);
        } else {
            $this->colleague1->Notify($message);
        }
    }
}

抽象出来的中介者和具体的实现,在这里,咱们假定有固定的两个同事类,让他们互相对话,因此进入的同事是1的时候,就去调用2的Notify方法,至关因而让2接收到了1发来的消息设计模式

abstract class Colleague
{
    protected $mediator;
    public function __construct(Mediator $mediator)
    {
        $this->mediator = $mediator;
    }

}

class ConcreteColleague1 extends Colleague
{
    public function Send(String $message)
    {
        $this->mediator->Send($message, $this);
    }
    public function Notify(String $message)
    {
        echo "同事1获得信息:" . $message, PHP_EOL;
    }
}

class ConcreteColleague2 extends Colleague
{
    public function Send(String $message)
    {
        $this->mediator->Send($message, $this);
    }
    public function Notify(String $message)
    {
        echo "同事2获得信息:" . $message;
    }
}

同事类及具体的实现,这里咱们要确认的一点就是,每个同事类,只认识中介者,并不认识另外的同事类,这就是中介者的特色,双方不用认识。数组

$m = new ConcreteMediator();

$c1 = new ConcreteColleague1($m);
$c2 = new ConcreteColleague2($m);

$m->colleague1 = $c1;
$m->colleague2 = $c2;

$c1->Send("吃过饭了吗?");
$c2->Send("没有呢,你打算请客?");

客户端的调用就比较很简单啦!微信

  • 是否是感受这个模式很适合作一些通信类的产品?没错,聊天社交、sns、直播之类的都很合适,由于这个模式就是能让用户与用户之间解耦,不须要让一个用户去维护全部有关联的用户对象
  • 由于不须要用户去维护关系,因此也就顺便解决了关系之间的多对多维护的问题,同时,也不须要去修改用户类来进行关系的变动,保持了用户类的良好封装
  • 可是,中介者集中维护可能致使这个类过于复杂和庞大
  • 因此,模式不是万能的,必定要弄清楚业务场景进行取舍地使用
  • 中介者适用于一组对象以定义良好可是复杂的方式进行通讯的场合,以及想定制一个分布在多个类中的行为,而又不想生成太多子类的场合

做为一名企业家,深知项目管理的重要性,而项目经理,在不少场合下就是一名中介者的角色。从组织角度看,一个项目的开始和结束,做为老板的我并不须要关心是由谁来具体编码实现,我要沟通的人只是项目经理。同理,其余辅助部门包括财务、人事、行政等,他们也不关心谁来写代码,而只须要和项目经理交流了解项目的状况以及须要配合的内容。在项目团队中,写代码的人呢?也不须要知道谁来给他发工资或者考勤问题出在哪里,这一切也交给项目经理解决就行了。因此说,项目经理负责制的项目开发,就是中介者模式的典型应用。咱们的手机厂之因此发展的如此之快,也多亏了这些项目经理们,晚上请他们吃大餐去咯~~~框架

完整代码:https://github.com/zhangyue0503/designpatterns-php/blob/master/15.mediator/source/mediator.php学习

实例

这回咱们不发短信了,实现一个聊天室吧。一个简单的在线聊天室,需求就是让进入聊天室的用户均可以在线聊天,让咱们来看看使用中介者模式来如何实现这个聊天室吧!this

聊天室类图

聊天室功能中介者模式版

完整源码:https://github.com/zhangyue0503/designpatterns-php/blob/master/15.mediator/source/mediator-webchat.php

<?php

abstract class Mediator
{
    abstract public function Send($message, $user);
}

class ChatMediator extends Mediator
{
    public $users = [];
    public function Attach($user)
    {
        if (!in_array($user, $this->users)) {
            $this->users[] = $user;
        }
    }

    public function Detach($user)
    {
        $position = 0;
        foreach ($this->users as $u) {
            if ($u == $user) {
                unset($this->users[$position]);
            }
            $position++;
        }
    }

    public function Send($message, $user)
    {
        foreach ($this->users as $u) {
            if ($u == $user) {
                continue;
            }
            $u->Notify($message);
        }
    }
}

abstract class User
{
    public $mediator;
    public $name;

    public function __construct($mediator, $name)
    {
        $this->mediator = $mediator;
        $this->name = $name;
    }
}

class ChatUser extends User
{
    public function Send($message)
    {
        $this->mediator->Send($message . '(' . $this->name . '发送)', $this);
    }
    public function Notify($message)
    {
        echo $this->name . '收到消息:' . $message, PHP_EOL;
    }
}

$m = new ChatMediator();

$u1 = new ChatUser($m, '用户1');
$u2 = new ChatUser($m, '用户2');
$u3 = new ChatUser($m, '用户3');

$m->Attach($u1);
$m->Attach($u3);
$m->Attach($u2);

$u1->Send('Hello, 你们好呀!'); // 用户二、用户3收到消息

$u2->Send('你好呀!'); // 用户一、用户3收到消息

$m->Detach($u2); // 用户2退出聊天室

$u3->Send('欢迎欢迎!'); // 用户1收到消息

说明

  • 有没有发现,中介者就是这个“聊天室”,由它来进行信息的传递转移
  • 这里因为不固定用户人数,所以是一个数组维护的,当用户发送消息的时候,除了他本身,其余人都收到了这条消息
  • 聊天室能够自由地进出用户,说实话,这个例子真的很像一个已经差很少实现功能了的聊天应用哦
  • 果真中介者模式真的很适合通讯方面的应用,可是,若是进入的用户很是多,$users列表就会愈来愈臃肿了哦,这就是上文中所述的中介者模式的问题所在

下期看点

中介者模式是否是颇有趣,在某些场景下也确实很是有用。可是就像以前说的,设计模式并非万能药,利用各类模式的组合才能造成完整的框架。这就是如今流行的各类框架的基础。因此,学以至用,而且合适的用,才是咱们学习的最终目标。别急别急,先把模式一个一个弄清楚了再说框架的事,下一个即将到来的是建造者模式,还请继续期待哟。

关注公众号:【硬核项目经理】获取最新文章

添加微信/QQ好友:【xiaoyuezigonggong/149844827】免费得PHP、项目管理学习资料

知乎、公众号、抖音、头条搜索【硬核项目经理】

B站ID:482780532

相关文章
相关标签/搜索