中介者模式,我的理解是,你的项目中存在许多级别平等的同事类实例,并且这些实例之间都需要有不同程度的各种交互操作活动。这个时候可以使用中介者模式来降低各同事类的耦合程度,每个同事类都只关心自己需要做什么,把耦合交互的工作交给中介类来完成。这里用了一个模拟电脑播放CD的例子来讲述这个问题。
这是一个标准定义中得中介者模式用例,在实际应用着,可能不需要所有的同事类都继承于一个父类,也不一定中介者类必须持有所有的同事用类。更多的时候中介者实例可能会用Singleton单例模式来设计。
1<?php 2 //抽象的同事类 3 abstract class Colleague{ 4 private $mediator; 5 6 public function __construct($mediator){ 7 if($mediator instanceof Mediator) 8 { 9 $this->mediator = $mediator; 10 } 11 else { 12 trigger_error("Input Object isn't Mediator Class Object!",E_USER_ERROR); 13 } 14 } 15 16 public function getMediator(){ 17 return $this->mediator; 18 } 19 } 20 21 //CD驱动器类 22 class CDDriver extends Colleague{ 23 public function __construct($mediator){ 24 parent::__construct($mediator); 25 } 26 27 //数据变量 28 private $data; 29 30 //获取光驱读取出来的数据 31 public function getData(){ 32 return $this->data; 33 } 34 35 //读取光盘 36 public function readCD(){ 37 $this->data = "设计模式,值得好好研究"; 38 //通知主板,自己的状态发生了改变 39 $this->getMediator()->changed($this); 40 } 41 42 } 43 44 //CPU类 45 class CPU extends Colleague{ 46 public function __construct($mediator){ 47 parent::__construct($mediator); 48 } 49 //视频数据 50 private $videoData; 51 //声音数据 52 private $soundData; 53 54 public function getVideoData(){ 55 return $this->videoData; 56 } 57 58 public function getSoundData(){ 59 return $this->soundData; 60 } 61 62 public function executeData($data){ 63 $dataArr = explode(",", $data); 64 $this->videoData = $dataArr[0]; 65 $this->soundData = $dataArr[1]; 66 $this->getMediator()->changed($this); 67 } 68 } 69 70 //显卡类 71 class VideoCard extends Colleague{ 72 public function __construct($mediator){ 73 parent::__construct($mediator); 74 } 75 public function showData($data){ 76 echo '您现在观看的是:'.$data; 77 } 78 } 79 80 //声卡类 81 class SoundCard extends Colleague{ 82 public function __construct($mediator){ 83 parent::__construct($mediator); 84 } 85 public function showData($data){ 86 echo '画外音:'.$data; 87 } 88 } 89 90 //定义中介者模式接口 91 interface Mediator{ 92 public function changed($colleague); 93 } 94 95 class MotherBoard implements Mediator{ 96 //定于中介对象需要掌握的所有需要交互的同事类 97 private $cdDriver,$cpu,$videoCard,$soundCard; 98 99 public function setCdDriver($cdDriver){ 100 $this->cdDriver = $cdDriver; 101 } 102 103 public function setCPU($cpu){ 104 $this->cpu = $cpu; 105 } 106 107 public function setVideoCard($videoCard){ 108 $this->videoCard = $videoCard; 109 } 110 111 public function setSoundCard($soundCard){ 112 $this->soundCard = $soundCard; 113 } 114 115 public function changed($colleague){ 116 if($colleague instanceof CDDriver){ 117 $this->opeCDDriverReadData($colleague); 118 } 119 else if($colleague instanceof CPU){ 120 $this->opeCPU($colleague); 121 } 122 } 123 124 private function opeCDDriverReadData($cd){ 125 $data = $cd->getData(); 126 $this->cpu->executeData($data); 127 } 128 129 private function opeCPU($cpu){ 130 $videoData = $cpu->getVideoData(); 131 $soundData = $cpu->getSoundData(); 132 $this->videoCard->showData($videoData); 133 echo '<br>'; 134 $this->soundCard->showData($soundData); 135 } 136 } 137 138 //创建中介对象:主板 139 $mediator = new MotherBoard(); 140 //创建各同事类:CD驱动,CPU,显卡,声卡 141 $cd = new CDDriver($mediator); 142 $cpu = new CPU($mediator); 143 $videoCard = new VideoCard($mediator); 144 $soundCard = new SoundCard($mediator); 145 //让中介类知道所有需要交互的同事类 146 $mediator->setCdDriver($cd); 147 $mediator->setCPU($cpu); 148 $mediator->setSoundCard($soundCard); 149 $mediator->setVideoCard($videoCard); 150 151 $cd->readCD(); 152?>