中介者模式(Mediator)
中介者模式(Mediator)就是用一个中介对象来封装一系列的对象交互,中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。 对于中介对象而言,所有相互交互的对象,都视为同事类,中介对象就是用来维护各个同事对象之间的关系,所有的同事类都只和中介对象交互,也就是说,中介对象是需要知道所有的同事对象的。当一个同事对象自身发生变化时,它是不知道会对其他同事对象产生什么影响,它只需要通知中介对象,“我发生变化了”,中介对象会去和其他同事对象进行交互的。这样一来,同事对象之间的依赖就没有了。有了中介者之后,所有的交互都封装在了中介对象里面,各个对象只需要关心自己能做什么就行,不需要再关心做了之后会对其他对象产生什么影响,也就是无需再维护这些关系了。
使用场景
- 如果一组对象之间的通信方式比较复杂,导致相互依赖,结构混乱,可以采用中介者模式
- 如果一个对象引用很多对象,并且跟这些对象交互,导致难以复用该对象
优缺点
优点
中介者主要是通过中介对象来封装对象之间的关系,使之各个对象在不需要知道其他对象的具体信息情况下通过中介者对象来与之通信。同时通过引用中介者对象来减少系统对象之间关系,提高了对象的可复用和系统的可扩展性。
缺点
中介者对象封装了对象之间的关联关系,导致中介者对象变得比较庞大,所承担的责任也比较多。它需要知道每个对象和他们之间的交互细节,如果它出问题,将会导致整个系统都会出问题。
角色解释
中介者接口(UnitedNations):在里面定义了各个同事之间相互交互所需要的方法。
具体的中介者实现对象(UnitedCommit):它需要了解并为维护每个同事对象,并负责具体的协调各个同事对象的交互关系。
同事类的定义(Country):通常实现成为抽象类,主要负责约束同事对象的类型,并实现一些具体同事类之间的公共功能,
具体的同事类(China):实现自己的业务,需要与其他同事对象交互时,就通知中介对象,中介对象会负责后续的交互。
示例代码
<?php
//中介者接口:可以是公共的方法,如Change方法,也可以是小范围的交互方法。
//同事类定义:比如,每个具体同事类都应该知道中介者对象,也就是每个同事对象都会持有中介者对象的引用,这个功能可定义在这个类中。
//抽象国家
abstract class Country
{
protected $mediator;
public function __construct(UnitedNations $_mediator)
{
$this->mediator = $_mediator;
}
}
//具体国家类
//美国
class USA extends Country
{
function __construct(UnitedNations $mediator)
{
parent::__construct($mediator);
}
//声明
public function Declared($message)
{
$this->mediator->Declared($message,$this);
}
//获得消息
public function GetMessage($message)
{
echo "美国获得对方消息:$message<br/>";
}
}
//中国
class China extends Country
{
public function __construct(UnitedNations $mediator)
{
parent::__construct($mediator);
}
//声明
public function Declared($message)
{
$this->mediator->Declared($message, $this);
}
//获得消息
public function GetMessage($message)
{
echo "中方获得对方消息:$message<br/>";
}
}
//抽象中介者
//抽象联合国机构
abstract class UnitedNations
{
//声明
public abstract function Declared($message,Country $colleague);
}
//联合国机构
class UnitedCommit extends UnitedNations
{
public $countryUsa;
public $countryChina;
//声明
public function Declared($message, Country $colleague)
{
if($colleague==$this->countryChina)
{
$this->countryUsa->GetMessage($message);
}
else
{
$this->countryChina->GetMessage($message);
}
}
}
测试代码
header("Content-Type:text/html;charset=utf-8");
//--------------------------中介者模式-------------------
require_once "./Mediator/Mediator.php";
//测试代码块
$UNSC = new UnitedCommit();
$c1 = new USA($UNSC);
$c2 = new China($UNSC);
$UNSC->countryChina = $c2;
$UNSC->countryUsa =$c1;
$c1->Declared("姚明的篮球打的就是好");
$c2->Declared("谢谢。");