php 设计模式之观察者模式
实例
没用设计模式的代码,这样的代码要是把最上面那部分也要符合要求加进来,就要修改代码,不符合宁增不改的原则
介绍
观察者模式定义对象的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新!
所有的观察者(observer)全部被注册(register函数)进入数组(事件的_observers[]数组),这样,当事件(例子中是paper)有变化的时候,就能通过遍历(代码19行)来通知所有的观察者。每个观察者再做他们自己对应的更新(代码20行)。
设计原则
在观察者模式中,会改变的是主题的状态以及观察者的数目。用这个模式,你可以改变依赖于主题状态的对象,却不必改变主题。——找出程序中会变化的方面,然后将其和固定不变的方面相分离!
主题和观察者都使用接口:观察者利用主题的接口向主题注册,而主题利用观察者接口通知观察者。这样可以让两者之间运作正常,又同时具有松耦合的优点! ——针对接口编程,不针对实现编程!
。
观察者模式利用“组合”将许多观察者组合进主题中。对象(观察者——主题)之间的这种关系不是通过继承产生的,而是在运行时利用组合的方式产生的。 ——多用组合,少用继承!
代码
1 <?php2 /**3 * 观察者模式4 * @author: Mac5 * @date: 2012/02/226 */
7
8
9 class Paper{ /*主题*/
10 private $_observers = array();11
12 public function register($sub){ /*注册观察者*/
13 $this->_observers[] = $sub;14 }15
16
17 public function trigger(){ /*外部统一访问*/
18 if(!empty($this->_observers)){19 foreach($this->_observers as $observer){20 $observer->update();21 }22 }23 }24 }25
26 /**27 * 观察者要实现的接口28 */
29 interfaceObserverable{30 public functionupdate();31 }32
33 class Subscriber implementsObserverable{34 public functionupdate(){35 echo "Callback\n";36 }37 }
下面是测试代码
1 /*测试*/
2 $paper = newPaper();3 $paper->register(newSubscriber());4 //$paper->register(new Subscriber1());5 //$paper->register(new Subscriber2());
6 $paper->trigger();
总结
当新对象要填入的时候,只需要在主题(又叫可观察者)中进行注册(注册方式很多,你也可以在构造的时候,或者框架访问的接口中进行注册),然后实现代码直接在新对象的接口中进行。这降低了主题对象和观察者对象的耦合度。
好的设计模式不会直接进入你的代码中,而是进入你的大脑中。
另一份代码
1 /**2 * 事件产生类3 * Class EventGenerator4 */
5 abstract classEventGenerator6 {7 private $ObServers =[];8
9 //增加观察者
10 public function add(ObServer $ObServer)11 {12 $this->ObServers[] = $ObServer;13 }14
15 //事件通知
16 public functionnotify()17 {18 foreach ($this->ObServers as $ObServer) {19 $ObServer->update();20 }21 }22
23 }24
25 /**26 * 观察者接口类27 * Interface ObServer28 */
29 interfaceObServer30 {31 public function update($event_info = null);32 }33
34 /**35 * 观察者136 */
37 class ObServer1 implementsObServer38 {39 public function update($event_info = null)40 {41 echo "观察者1 收到执行通知 执行完毕!\n";42 }43 }44
45 /**46 * 观察者147 */
48 class ObServer2 implementsObServer49 {50 public function update($event_info = null)51 {52 echo "观察者2 收到执行通知 执行完毕!\n";53 }54 }55
56 /**57 * 事件58 * Class Event59 */
60 class Event extendsEventGenerator61 {62 /**63 * 触发事件64 */
65 public functiontrigger()66 {67 //通知观察者
68 $this->notify();69 }70 }71
72 //创建一个事件
73 $event = newEvent();74 //为事件增加旁观者
75 $event->add(newObServer1());76 $event->add(newObServer2());77 //执行事件 通知旁观者
78 $event->trigger();