GoF定义:用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互
聊天社交、sns、直播之类的都很适合这个模式,因为这个模式就是能让用户与用户之间解耦,不需要让一个用户去维护所有有关联的用户对象
- 因为不需要用户去维护关系,所以也就顺便解决了关系之间的多对多维护的问题,同时,也不需要去修改用户类来进行关系的变更,保持了用户类的良好封装
- 但是,中介者集中维护可能导致这个类过于复杂和庞大
- 所以,模式不是万能的,一定要弄清楚业务场景进行取舍地使用
- 中介者适用于一组对象以定义良好但是复杂的方式进行通信的场合,以及想定制一个分布在多个类中的行为,而又不想生成太多子类的场合
GoF类图:
PHP:
<?php
/*
* 抽象出来的中介者和具体的实现
* 在这里,我们假定有固定的两个同事类,让他们互相对话,所以进入的同事是1的时候,就去调用2的Notify方法,相当于是让2接收到了1发来的消息
*/
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);
}
}
}
/*
* 同事类及具体的实现
* 这里我们要确认的一点就是,每一个同事类,只认识中介者,并不认识另外的同事类,这就是中介者的特点,双方不用认识。
*/
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, PHP_EOL;
}
}
$m = new ConcreteMediator();
$c1 = new ConcreteColleague1($m);
$c2 = new ConcreteColleague2($m);
$m->colleague1 = $c1;
$m->colleague2 = $c2;
$c1->Send("吃过饭了吗?");
$c2->Send("没有呢,你打算请客?");
文档信息
- 本文作者:carpe
- 本文链接:https://carpedx.com/wiki/design-pattern-tertium-quid/
- 版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)