定义:
中介者模式(Mediator):用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
结构:
- Mediator:抽象中介者,定义了同事对象到中介者对象的接口。
- Colleague:抽象同事类。
- ConcreteMediator:具体中介者对象,实现抽象类的方法,它需要知道所有具体同事类,并从具体同事接收消息,向具体同事对象发出命令。
- ConcreteColleague:具体同事类,每个具体同事只知道自己的行为,而不了解其它同事类的情况,但它们却都认识中介者对象。
- Client:客户端代码。
代码实例:
/** * 抽象中介者 * Class Mediator */ abstract class Mediator { /** * 定义一个抽象的发送消息方法,得到同事对象和发送消息 * @param string $message 要发送的消息 * @param Colleague $colleague 同事对象 * @return mixed */ abstract public function send($message, Colleague $colleague); } /** * 抽象同事类 * Class Colleague */ abstract class Colleague { /** * 中介者对象 * @var Mediator */ protected $mediator; public function __construct(Mediator $mediator) { $this->mediator = $mediator; } } /** * 具体中介者对象 * Class ConcreteMediator */ class ConcreteMediator extends Mediator { /** * 具体同事对象ConcreteColleague1 * @var */ private $colleague1; /** * 具体同事对象ConcreteColleague2 * @var */ private $colleague2; /** * @param $c1 */ public function setColleague1($c1) { $this->colleague1 = $c1; } /** * @param $c2 */ public function setColleague2($c2) { $this->colleague2 = $c2; } /** * 重写发送消息的方法,根据对象做出判断选择,通知相应的对象 * @param string $message * @param Colleague $colleague * @return mixed|void */ public function send($message, Colleague $colleague) { // TODO: Implement send() method. if ($colleague == $this->colleague1) { $this->colleague2->notify($message); } else { $this->colleague1->notify($message); } } } /** * 具体同事类 * Class ConcreteColleague1 */ class ConcreteColleague1 extends Colleague { /** * 发送消息 * @param $message */ public function send($message) { $this->mediator->send($message, $this); } /** * 得到消息 * @param $message */ public function notify($message) { echo "ConcreteColleague1得到消息:{$message}<br>"; } } /** * 具体同事类 * Class ConcreteColleague2 */ class ConcreteColleague2 extends Colleague { /** * 发送消息 * @param $message */ public function send($message) { $this->mediator->send($message, $this); } /** * 得到消息 * @param $message */ public function notify($message) { echo "ConcreteColleague2得到消息:{$message}<br>"; } } ##客户端代码 $m = new ConcreteMediator(); $c1 = new ConcreteColleague1($m); $c2 = new ConcreteColleague2($m); $m->setColleague1($c1); $m->setColleague2($c2); $c1->send("下班了吗?"); $c2->send("还没呢,今晚加班。"); ##测试结果 ConcreteColleague2得到消息:下班了吗? ConcreteColleague1得到消息:还没呢,今晚加班。
总结:
- 中介者模式中Mediator的出现减少了各个Colleague的耦合,使得可以独立地改变和复用各个Colleague类和Mediator.
- 中介者模式由于把对象如何协作进行了抽象,将中介作为一个独立的概念并将其封装在一个对象中,这样关注的对象就从对象各自本身的行为转移到它们之间的交互上来,也就是站在一个更宏观的角度去看待系统。
- 中介者模式由于ConcreteMediator控制了集中化,于是就把交互复杂性变为了中介者的复杂性,这就使得中介者会变得比任何一个ConcreteColleague都复杂。
- 中介者模式一般应用于一组对象以定义良好但是复杂的方式进行通信的场合,以及想定制一个分布在多个类中的行为,而又不想生成太多子类的场合。