什么是观察者模式
从面向过程的角度来看,首先是观察者向主体注册,注册完之后,主体再通知观察者做出相应的操作,整个事情就完了
从面向对象的角度来看,主体提供对观察者管理的接口(注册,取消,通知),观察者提供自身操作的接口。(这些观察者拥有一个同一个的接口)观察者利用主体的接口向主体注册,而主体理由观察者接口通知观察者。耦合度相当之低。
为什么要使用观察者模式
观察者模式更多体现了两个独立的类利用接口完成一件本应该很复杂的事情。不利用主体类的话,我们还需要不断循环创建实例,执行操作。而现在只需要创建实例就好,执行操作的事儿只需要调用一次通知的方法就好啦
应用场景
当一个对象的发生改变时所有依赖于它的对象都需要得到通知并被自动更新,而且它不知道具体有多少对象有待通知,应该考虑使用观察者模式。
示例代码
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 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
| <?php
class Newspaper implements SplSubject { private $name; private $observers; private $content; public function __construct($name){ $this->$name = $name; $this->observers = new SplObjectStorage(); } public function attach(SplObserver $observer){ $this->observers->attach($observer); } public function detach(SplObserver $observer){ $this->observers->detach($observer); } public function notify(){ foreach ($this->observers as $observer) { $observer->update($this); } } public function getContent(){ return $this->content."{$this->name}"; } public function breakOutNews($content) { $this->content = $content; $this->notify(); } }
class Reader implements SplObserver { private $name; public function __construct($name){ $this->name = $name; } public function update(SplSubject $subject) { echo $this->name.' is reading breakout news'.$subject->getContent(); } }
class WorkFlow { public function run() { $newspaper = new Newspaper('New York Times'); $allen = new Reader("allen"); $jimmy = new Reader("jimmy"); $tom = new Reader("tom"); $newspaper->attach($allen); $newspaper->attach($jimmy); $newspaper->attach($tom); $newspaper->detach($tom); $newspaper->breakOutNews('USA BREAK DOWN'); } } $work = new WorkFlow(); $work->run();
|