为交互对象之间的松耦合设计而努力
观察者模式定义了对象之间的一对多的依赖,这样以来,当一个对象改变状态,它的所有的依赖者都会收到通知并自动更新。
如图,当主题有消息更新的时候,小猫和小狗会收到通知,此时小猪不在观察者里, 需要进行注册,然后就可以收到通知了。
模式中的角色
抽象主题(Subject):它把所有观察者对象的引用保存到一个聚集里,每个主题都可以有任何数量的观察者。抽象主题提供一个接口,可以增加和删除观察者对象。
具体主题(ConcreteSubject):将有关状态存入具体观察者对象;在具体主题内部状态改变时,给所有登记过的观察者发出通知。
抽象观察者(Observer):为所有的具体观察者定义一个接口,在得到主题通知时更新自己。
具体观察者(ConcreteObserver):实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题状态协调。
1 interface WeatherCenter 2 { 3 public function registerObserver(Observer $observer); 4 public function removeObserver(Observer $observer); 5 public function notifyObserver(); 6 } 7 8 interface Observer 9 { 10 public function update(); 11 }
类实现:
//合肥天气中心 class HefeiWeaterCenter implements WeatherCenter { protected $observers = []; protected $temperature; public function registerObserver(Observer $observer) { $this -> observers[] = $observer; } public function removeObserver(Observer $observer) { $newObservers = []; foreach($this -> observers as $obs) { if($obs !== $observer) { $newObservers[] = $obs; } } $this -> observers = $newObservers; } public function notifyObserver() { foreach($this -> observers as $observer) { $observer -> update(); } } public function TemperatureChanged($temperature) { $this -> temperature = $temperature; $this -> notifyObserver(); } public function getWeather() { return $this -> temperature; } } class ForecastWeather implements Observer { protected $WeatherCenter; public function __construct(WeatherCenter $weathercenter) { $this -> WeatherCenter = $weathercenter; $this -> WeatherCenter -> registerObserver($this); } public function update() { echo "ForecastWeather {$this -> WeatherCenter -> getWeather()} "; } public function remove() { $this -> WeatherCenter -> removeObserver($this); } } class StaticWeather implements Observer { protected $WeatherCenter; public function __construct(WeatherCenter $weathercenter) { $this -> WeatherCenter = $weathercenter; $this -> WeatherCenter -> registerObserver($this); } public function update() { echo "StaticWeather {$this -> WeatherCenter -> getWeather()} "; } public function remove() { $this -> WeatherCenter -> removeObserver($this); } } $HefeiWeatherCenter = new HefeiWeaterCenter(); $HefeiForecast = new ForecastWeather($HefeiWeatherCenter); $HefeiStatic = new StaticWeather($HefeiWeatherCenter); $HefeiWeatherCenter -> TemperatureChanged(27); $HefeiWeatherCenter -> TemperatureChanged(30);
输出
1 ForecastWeather 27 2 StaticWeather 27 3 ForecastWeather 30 4 StaticWeather 30