观察者模式是一种事件系统,意味着这一模式允许某个类观察另一个类的状态,当被观察的类状态发生改变的时候,观察类可以收到通知并且做出相应的动作,观察者模式提供了避免组件之间紧密耦合的另一种方式。
在观察者模式中,被观察者称为subject,观察者称为observer,为了表达这些内容,SPL(Standard PHP Libaray)提供了SplSubject(被观察者)和SplObserver(观察者)两个接口。在编写观察者模式时,只要实现这两个接口即可。接口如下:
1 2 3 4 5 6 7 8 9 10
| interface SplSubject{ public function attach(SplObserver $observer); public function detach(SplObserver $observer); public function notify(); } interface SplObserver{ public function update(SplSubject $subject); }
|
这一模式的概念是SplSubject类维护了一个特定状态,当这个状态发生变化时,它就会调用notify()方法。调用notify()方法时,所有之前使用attach()方法注册的SplObserver实例的update方法都会被调用。 以下是实现代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| <?php
class DemoSubject implements SplSubject { private $observers; private $value; public function __construct() { $this->observers = array(); }
public function attach(SplObserver $observer) { $this->observers\[\] = $observer; } public function detach(SplObserver $observer) { if($idx = array_search($observer,$this->observers,true)) { unset($this->observers\[$idx\]); } } public function notify() { foreach($this->observers as $observer) { $observer->update($this); } }
public function setState($value) { $this->value = $value; $this->notify(); }
public function getValue() { return $this->value; } }
class DemoObserver implements SplObserver { public function update(SplSubject $subject) { echo 'The new value is '. $subject->getValue(); } } $subject = new DemoSubject(); $observer = new DemoObserver(); $subject->attach($observer); $subject->setState(5); ?>;
|
输出结果为: The new value is 5 观察者模式的优点在于,挂接到被观察者上的观察者可多可少,并且不需要提前知道哪个观察者会响应被观察者发出的响应事件。 这种设计模式在很多PHP框架中都被使用到,如Yii等。