PHP 观察者模式
观察者模式(Observer),当一个对象的状态发生改变时,依赖他的对象会全部收到通知,并自动更新,从而实现了低耦合,非侵入式的通知与更新机制。
1 class Book { 2 3 private $observers = array(); 4 5 public $content = ''; 6 7 //添加观察者 8 public function attach($observer){ 9 $this->observers[] = $observer; 10 } 11 12 //删除观察者 13 public function detach($observer){ 14 15 $key = array_search($observer, $this->observers, true); 16 if($key) unset($this->observers[$key]); 17 } 18 19 //通知观察者 20 public function notify(){ 21 22 foreach ($this->observers as $obj){ 23 $obj->update($this); 24 } 25 } 26 27 //设置内容 28 public function setContent($content){ 29 30 $this->content = $content; 31 } 32 33 34 } 35 36 37 38 class Person { 39 40 public $name; 41 42 public function __construct($name){ 43 $this->name = $name; 44 } 45 46 public function update($observable){ 47 48 echo $this->name . ' 看到: ' . $observable->content . "\n"; 49 } 50 51 } 52 53 //创建被监视对象 54 $book = new Book(); 55 56 //创建两个观察者 57 $person1 = new Person('张三'); 58 $person2 = new Person('李四'); 59 60 //添加两个观察者 61 $book->attach($person1); 62 $book->attach($person2); 63 64 65 //被监视对象发生改变 66 $book->setContent('无论我们最后生疏到什么样子,曾经我对你的好,是真心的。'); 67 68 //通知所有观察者 69 $book->notify();
另外,PHP有提供两个接口和一个类,来实现观察者模式。
1 class Observable implements SplSubject{ 2 3 private $storage; 4 5 function __construct(){ 6 $this->storage = new SplObjectStorage(); 7 } 8 9 function attach(SplObserver $observer){ 10 $this->storage->attach($observer); 11 } 12 13 function detach(SplObserver $observer){ 14 $this->storage->detach($observer); 15 } 16 17 function notify(){ 18 19 foreach ($this->storage as $obj) { 20 $obj->update($this); 21 } 22 } 23 24 } 25 26 abstract class Observer implements SplObserver { 27 28 private $observable; 29 30 function __construct(Observable $observable){ 31 32 $this->observable = $observable; 33 $observable->attach($this); 34 } 35 36 function update(SplSubject $subject){ 37 38 if ($subject === $this->observable){ 39 $this->doUpdate($subject); 40 } 41 } 42 43 abstract function doUpdate(Observable $observable); 44 } 45 46 47 48 class ConcreteObserver extends Observer{ 49 50 function doUpdate(Observable $observable){ 51 52 } 53 }