在前面已经讲过的设计模式中,不少模式都是通过分割出多个对象来提高代码的复用性的,比如职责链模式和桥接模式,但是随着对象的增加,对象与对象之间的联系又和使系统呈现紧耦合,不易改动。
有没有一种方法来解决这个问题呢?
答案是中介模式,中介模式通过建立一个中介者,把对象与对象之间的直接联系转化为对象联系中介,中介再联系另一个对象的方式,使原先对象与对象之间复杂的连接关系简化为一个以中介者为核心的拓扑结构。
中介模式中主要包括中介对象和同事对象,同事对象间的联系通过中介对象来进行连接,所有中介对象必须知道所有同事对象而同事对象不需要。
这里通过婚姻介绍所的例子来演示中介模式的用法。
在这里婚姻介绍所就是中介对象,广大剩男剩女就是同事对象。
首先定义抽象中介类:
abstract class mediator{
abstract function send($message,$collegueName,collegue $collegue);
}
婚姻介绍所类
class marrigeAgency extends mediator {
//婚姻介绍所的客户列表
private $collegueList=array();
function addCollegue(collegue $collegue){
$this->collegueList[$collegue->name]=$collegue;
}
//中介需要知道的信息:消息内容,发给谁,谁发的
function send($message,$collegueName,collegue $collegue)
{
if (isset($this->collegueList[$collegueName])){
$this->collegueList[$collegueName]->notify($message,$collegue);
}else{
throw new Exception('勾搭失败,客户不存在');
}
}
}
抽象同事类
abstract class collegue{
public $name;
protected $mediator;
public function __construct($name,$mediator)
{
$this->name = $name;
//每个成员都需要依赖婚姻介绍所这个中介
$this->mediator = $mediator;
}
//客户发送消息需要的信息:要发送的消息内容,发给谁
abstract function send($message,$name);
}
婚姻介绍所客户类(具体同事类)
class people extends collegue {
function send($message, $name)
{
//通过中介者发送消息实际上就是调用中介的方法
$this->mediator->send($message,$name,$this);
}
//如果成功发送信息则会调用该方法
function notify($message,collegue $collegue){
echo $this->name."已经收到"."消息:$message<br>(来自$collegue->name)<br>";
}
}
客户端代码:
$agency=new marrigeAgency();
//每个客户都需要认识中介
$boy1=new people('小明',$agency);
$boy2=new people('小强',$agency);
$gril1=new people('小花',$agency);
$gril2=new people('小丽',$agency);
//中介需要认识每个客户
$agency->addCollegue($boy1);
$agency->addCollegue($boy2);
$agency->addCollegue($gril1);
$agency->addCollegue($gril2);
$boy1->send('我要约你','小花');
$gril1->send('好啊好啊','小明');
$boy2->send('我要约你','小丽');
$gril2->send('丑拒','小强');
显示结果:
总结
当系统出现多个对象与多个对象进行通信的时候,先不要急着使用中介模式,首先考虑能不能优化系统的结构。通过中介模式,的确我们解耦了同事对象与同事对象之间的联系,但是解除通信的复杂性的代价就是造成了中介者的复杂性,系统 过于依赖中介者。所以中介者一般应用在多个对象定义良好需要复杂通信的场所,定义一个分布在多个类的行为的场合而不想定义过多子类