中介者模式,我的理解是,你的项目中存在许多级别平等的同事类实例,并且这些实例之间都需要有不同程度的各种交互操作活动。这个时候可以使用中介者模式来降低各同事类的耦合程度,每个同事类都只关心自己需要做什么,把耦合交互的工作交给中介类来完成。这里用了一个模拟电脑播放CD的例子来讲述这个问题。
这是一个标准定义中得中介者模式用例,在实际应用着,可能不需要所有的同事类都继承于一个父类,也不一定中介者类必须持有所有的同事用类。更多的时候中介者实例可能会用Singleton单例模式来设计。
<?php
//抽象的同事类
abstract class Colleague{
private $mediator;
public function __construct($mediator){
if($mediator instanceof Mediator)
{
$this->mediator = $mediator;
}
else {
trigger_error("Input Object isn't Mediator Class Object!",E_USER_ERROR);
}
}
public function getMediator(){
return $this->mediator;
}
}
//CD驱动器类
class CDDriver extends Colleague{
public function __construct($mediator){
parent::__construct($mediator);
}
//数据变量
private $data;
//获取光驱读取出来的数据
public function getData(){
return $this->data;
}
//读取光盘
public function readCD(){
$this->data = "设计模式,值得好好研究";
//通知主板,自己的状态发生了改变
$this->getMediator()->changed($this);
}
}
//CPU类
class CPU extends Colleague{
public function __construct($mediator){
parent::__construct($mediator);
}
//视频数据
private $videoData;
//声音数据
private $soundData;
public function getVideoData(){
return $this->videoData;
}
public function getSoundData(){
return $this->soundData;
}
public function executeData($data){
$dataArr = explode(",", $data);
$this->videoData = $dataArr[0];
$this->soundData = $dataArr[1];
$this->getMediator()->changed($this);
}
}
//显卡类
class VideoCard extends Colleague{
public function __construct($mediator){
parent::__construct($mediator);
}
public function showData($data){
echo '您现在观看的是:'.$data;
}
}
//声卡类
class SoundCard extends Colleague{
public function __construct($mediator){
parent::__construct($mediator);
}
public function showData($data){
echo '画外音:'.$data;
}
}
//定义中介者模式接口
interface Mediator{
public function changed($colleague);
}
class MotherBoard implements Mediator{
//定于中介对象需要掌握的所有需要交互的同事类
private $cdDriver,$cpu,$videoCard,$soundCard;
public function setCdDriver($cdDriver){
$this->cdDriver = $cdDriver;
}
public function setCPU($cpu){
$this->cpu = $cpu;
}
public function setVideoCard($videoCard){
$this->videoCard = $videoCard;
}
public function setSoundCard($soundCard){
$this->soundCard = $soundCard;
}
public function changed($colleague){
if($colleague instanceof CDDriver){
$this->opeCDDriverReadData($colleague);
}
else if($colleague instanceof CPU){
$this->opeCPU($colleague);
}
}
private function opeCDDriverReadData($cd){
$data = $cd->getData();
$this->cpu->executeData($data);
}
private function opeCPU($cpu){
$videoData = $cpu->getVideoData();
$soundData = $cpu->getSoundData();
$this->videoCard->showData($videoData);
echo '<br>';
$this->soundCard->showData($soundData);
}
}
//创建中介对象:主板
$mediator = new MotherBoard();
//创建各同事类:CD驱动,CPU,显卡,声卡
$cd = new CDDriver($mediator);
$cpu = new CPU($mediator);
$videoCard = new VideoCard($mediator);
$soundCard = new SoundCard($mediator);
//让中介类知道所有需要交互的同事类
$mediator->setCdDriver($cd);
$mediator->setCPU($cpu);
$mediator->setSoundCard($soundCard);
$mediator->setVideoCard($videoCard);
$cd->readCD();
?>