Observer观察者设计模式,用于解决项目中一对多业务关系的设计模式,比如报纸的订阅。一份报纸可以有N个人订阅。这个用例是模拟了一个水质监控的实际需求。水质被分为了0~3级的污染程度,当水质发生相应变化,就要通知相应级别的工作人员进行相应的处理工作。这样就成了一个Subject有N个业务人员需要关注的问题。
当然,在实际应用中,还是有相应的一些变化,比如报纸即可以有N个人定,一个人也可以订N份报纸。互为观察者和观察目标的情况也是有可能的。
duty = $duty; } public function setDuty($duty){ $this->duty = $duty; } public function getDuty(){ return $this->duty; } public function update($subject){ echo "".$this->duty."获取到通知,当期的污染级别为:".$subject->getPolluteLevel().""; } } //定义水质监测的目标对象 abstract class WaterQualitySubject{ protected $watcherArray = array(); //为观察对象加入观察者 public function attach($observer){ array_push($this->watcherArray, $observer); } //删除不需要的观察者,我就不具体实现了 public function remove($observer){ } public abstract function notifyWatchers(); public abstract function getPolluteLevel(); } class WaterQuality extends WaterQualitySubject{ //污染的级别,0~3 private $polluteLevel = 0; public function getPolluteLevel(){ return $this->polluteLevel; } public function setPolluteLevel($polluteLevel){ //被观察的对象发生了改变 $this->polluteLevel = $polluteLevel; //通知有所符合要求的观察者 $this->notifyWatchers(); } public function notifyWatchers(){ foreach ($this->watcherArray as $key => $value) { if($this->polluteLevel >= 0){ //通知监测人员 if($this->watcherArray[$key]->getDuty() == '监测人员'){ $this->watcherArray[$key]->update($this); } } if($this->polluteLevel >= 1){ //通知预警人员 if($this->watcherArray[$key]->getDuty() == '预警人员'){ $this->watcherArray[$key]->update($this); } } if($this->polluteLevel >= 2){ //通知监测部门领导 if($this->watcherArray[$key]->getDuty() == '监测部门领导'){ $this->watcherArray[$key]->update($this); } } } } } //测试一下 //创建要监测的项目 $subject = new WaterQuality(); //创建几个观察者 $watcher1 = new Watcher('监测人员'); $watcher2 = new Watcher('预警人员'); $watcher3 = new Watcher('监测人员'); $watcher4 = new Watcher('监测部门领导'); //把创建好的观察者加入到监测的项目中 $subject->attach($watcher1); $subject->attach($watcher2); $subject->attach($watcher3); $subject->attach($watcher4); echo '当水质为正常值得时候:'; $subject->setPolluteLevel(0); echo '当水质为轻度污染得时候:'; $subject->setPolluteLevel(1); echo '当水质为重度污染得时候:'; $subject->setPolluteLevel(2); ?>