github地址:https://github.com/ZQCard/design_pattern
/** * 當對象間存在一對多關系時,則使用觀察者模式(Observer Pattern)。 * 比如,當一個對象被修改時,則會自動通知它的依賴對象。觀察者模式屬於行為型模式。 * 一個對象(目標對象)的狀態發生改變,所有的依賴對象(觀察者對象)都將得到通知,進行廣播通知。 */
(1) Subject.class.php(目標類)
<?php namespace Observer; class Subject { private $state; private $observers = []; public function getState() { return $this->state; } public function seState($state) { $this->state = $state; $this->notifyAllObjects(); } public function register(Observer $object) { $this->observers[] = $object; } public function remove($object) { foreach ($this->observers as $key => $observer) { if ($observer == $object){ unset($this->observers[$key]); } } } public function notifyAllObjects() { foreach ($this->observers as $observer) { $observer->update(); } } }
(2)Observer.class.php(觀察者抽象父類)
<?php namespace Observer; abstract class Observer { protected $subject; public abstract function update(); }
(3)ObjectA.class.php (具體抽象類A)
<?php namespace Observer; class ObserverA extends Observer { private $myState = 'init A'; public function __construct(Subject $subject) { $this->subject = $subject; $this->subject->register($this); } public function update() { $this->myState = $this->subject->getState(); } public function getSate() { return "ObserverA get state:".$this->myState; } }
(4)ObserverB.class.php(具體觀察者B)
<?php namespace Observer; class ObserverB extends Observer { private $myState = 'init B'; public function __construct(Subject $subject) { $this->subject = $subject; $this->subject->register($this); } public function update() { $this->myState = $this->subject->getState(); } public function getSate() { return "ObserverB get state:".$this->myState; } }
(5)observer.php
<?php spl_autoload_register(function ($className){ $className = str_replace('\\','/',$className); include $className.".class.php"; }); use Observer\ObserverA; use Observer\ObserverB; use Observer\Subject; /*
ObserverA get state:init A
ObserverB get state:init B
ObserverA get state:hello
ObserverB get state:hello
*/
$subject = new Subject(); $objectA = new ObserverA($subject); $objectB = new ObserverB($subject); echo $objectA->getSate(); echo '<br/>'; echo $objectB->getSate(); echo '<br/>'; $subject->seState("hello"); echo $objectA->getSate(); echo '<br/>'; echo $objectB->getSate(); echo '<br/>';
