观察者模式比较适合这样一种业务:一个事件发生,导致多个类型的业务逻辑处理。举个不太恰当的网站的注册事件:业务说,用户注册以后,手机要给用户发短信,邮箱要给他发邮件。那么这个注册就是发生的事件,发短信和发邮件就是两个业务。为了短信和邮件不耦合,就可以使用观察者模式。
这里,有两个观察者,一个手机,一个邮箱。触发手机业务和触发邮箱业务,我可以定义一个接口包括update()方法代表业务触发,这两个业务类要实现我这个接口。
观察者模式里有个目标,这个目标就相当于注册事件。我把那两个观察者注册到目标里,目标发生了什么,我就会通知这两个观察者。
大致就是这样,简单写一下样例。
定义一个接口。这个触发事件,传入这个目标(比如注册)的信息。
<?php interface Observer{ public function update(Subject $subject); }
两个观察者各自实现这个接口。
1 <?php 2 3 class ObserverA implements Observer{ 4 5 function update($subject){ 6 echo 'A的业务:', $subject->getEvent(), '<br/>'; 7 } 8 }
1 <?php 2 3 class ObserverB implements Observer{ 4 5 function update($subject){ 6 echo 'B的业务:', $subject->getEvent(), '<br/>'; 7 } 8 }
然后就是目标:这里可以让目标继承一个抽象类。实现几个方法。我就直接写目标类了。。
1 <?php 2 3 class Subject{ 4 5 private $observers = array();// 观察者数组 6 7 private $event = null;// 目标发生的事件 8 9 function __construct($info = null) 10 { 11 $this->event = $info; 12 } 13 14 function getEvent(){ 15 return $this->event; 16 } 17 18 function addObj($observer){ 19 $this->observers[] = $observer; 20 } 21 22 function notify(){ 23 foreach($this->observers as $val){ 24 $val->update($this); 25 } 26 } 27 }
测试样例:
1 <?php 2 3 include '......这几个文件'; 4 5 $subject = new Subject('发生了什么事件,也可以不传入(表示只是个通知)'); 6 7 $observerA = new ObserverA(); 8 $observerB = new ObserverB(); 9 10 $subject->addObj($observerA); 11 $subject->addObj($observerB); 12 13 $subject->notify();