设计模式之观察者模式PHP实现
1、观察者模式:定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并且有所作为。即出版者+订阅者=观察者模式。
2、例子类图概览:
3、假设我们需要实现一个气象台,当气象信息更新时候,通知到每一个布告板上。
(1)我们根据上图将所需接口列出如下:
<?php /** * 主题接口 * Interface Subject */ interface Subject{ public function registerObserver(Observer $O); public function removeObserver(Observer $O); public function notifyObservers(); }
<?php /** * 观察者接口 * Interface Observer */ interface Observer{ public function update($fltTemperature, $fltHumidity, $fltPressure); }
<?php /** * 展示接口 * Interface DisplayElement */ interface DisplayElement{ public function display(); }
(2)然后我们实现主题接口如下:
<?php class WeatherData implements Subject{ public $arrObserver = array(); public $fltTemperature; public $fltHumidity; public $fltPressure; /** * 添加观察对象 * @param Observer $O */ public function registerObserver(Observer $O) { $this->arrObserver[] = $O; } /** * 移除观察对象 * @param Observer $O */ public function removeObserver(Observer $O) { foreach ($this->arrObserver as $key => $o){ if($o == $O){ unset($this->arrObserver[$key]); } } } /** * 通知观察对象更新数据 */ public function notifyObservers() { foreach ($this->arrObserver as $key => $o){ $o->update($this->fltTemperature, $this->fltHumidity, $this->fltPressure); } } /** * 当信息更新时候调用通知接口 */ public function measurementsChange(){ $this->notifyObservers(); } /** * 更新信息 * @param $fltTemperature * @param $fltHumidity * @param $fltPressure */ public function setMeasurements($fltTemperature, $fltHumidity, $fltPressure){ $this->fltTemperature = $fltTemperature; $this->fltHumidity = $fltHumidity; $this->fltPressure = $fltPressure; $this->measurementsChange(); } }
(3)我们再实现观察者接口如下:
<?php /** * 当前天气情况布告板 * Class CurrentCondition */ class CurrentCondition implements Observer, DisplayElement{ public $fltTemperature; public $fltHumidity; public $fltPressure; public function update($fltTemperature, $fltHumidity, $fltPressure) { $this->fltTemperature = $fltTemperature; $this->fltHumidity = $fltHumidity; $this->fltPressure = $fltPressure; $this->display(); } public function display() { echo "now condition is: temperatur={$this->fltTemperature}, humidity={$this->fltHumidity}, pressure={$this->fltPressure}"; } }
<?php /** * 天气预报接口 * Class Forcast */ class Forcast implements Observer, DisplayElement{ public $fltTemperature; public $fltHumidity; public $fltPressure; public function update($fltTemperature, $fltHumidity, $fltPressure) { $this->fltTemperature = $fltTemperature; $this->fltHumidity = $fltHumidity; $this->fltPressure = $fltPressure; $this->display(); } public function display() { if($this->fltTemperature > 30 && $this->fltHumidity > 70 && $this->fltPressure > 80){ echo 'it will be hot'; }else{ echo 'it will be cool'; } } }
(4)最后我们对相关接口进行调用输出:
<?php $objWeather = new WeatherData(); $objWeather->setMeasurements(40,20,50.9); $objWeather->setMeasurements(20,40,30.7); $objWeather->setMeasurements(10,50,60.2);