Observer - 观察者模式

来源:互联网 发布:淘宝美工难吗 编辑:程序博客网 时间:2024/05/29 09:45

观察者模式:

<?phpinterface Subject{public function notify();public function attach(Observer $observer);public function detach(Observer $observer);}class LoginSubject implements Subject{private static $observers = array();public function attach(Observer $observer){if (!array_search($observer, self::$observers)) {self::$observers[] = $observer;}}public function detach(Observer $observer){foreach (self::$observers as $obs) {if ($obs != $observer) {$newObservers[] = $obs;}}self::$observers = $newObservers;}public function notify(){foreach (self::$observers as $obs) {$obs->update($this);}}public function login(){// 处理登录,设置登录状态// setStatus();}// 返回登录状态信息public function getStatus(){switch(rand(1,3)) {case 1:$status = array('200', 'vboy1', '127.0.0.1');break;case 2:$status = array('400', 'vboy2', '127.0.0.2');break;case 3:$status = array('500', 'vboy3', '127.0.0.3');break;}return $status;}}interface Observer{public function update(Subject $subject);}abstract class LoginObserver implements Observer{private $_login;public function __construct(LoginSubject $loginSubject){$this->_login = $loginSubject;$loginSubject->attach($this);}public function update(Subject $subject){if ($subject === $this->_login) { // 保证调用update函数的对象是LoginSubject类型$this->doUpdate($subject);}}abstract public function doUpdate(LoginSubject $loginSubject);}class log extends LoginObserver{public function doUpdate(LoginSubject $loginSubject){$status = $loginSubject->getStatus();if ($status[0] == '200') {// Logger::successLogin(); // 记录登录日志}}}class mail extends LoginObserver{public function doUpdate(LoginSubject $loginSubject){$status = $loginSubject->getStatus();if ($status[0] == '400') {// Mailer::send(); // 发邮件通知管理员}}}$loginSubject = new LoginSubject();new log($loginSubject);new mail($loginSubject);$loginSubject->notify();


另外,PHP通过内置的SPL扩展,提供了对观察者模式的原生支持。SPL是一套可以帮助PHP程序员处理很多面向对象问题的工具,堪称是一把面向对象的瑞士军刀。

SplObjectStorage是一个工具类,用于更好的存储对象和删除对象。

如下所示:

<?phpclass Login implements SplSubject{private $_observers;public function __construct(){$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 $obs) {$obs->update($this);}}public function getStatus(){switch(rand(1,3)) {case 1:$res = 1;break;case 2:$res = 2;break;case 3:$res = 3;break;}return $res;}}abstract class LoginObserver implements SplObserver{private $login;public function __construct(Login $login){$this->_login = $login;$login->attach($this);}public function update(SplSubject $subject){if ($subject === $this->_login) {$this->doUpdate($subject);}}abstract function doUpdate(Login $login);}class log extends LoginObserver{public function doUpdate(Login $login){echo __CLASS__ . ':' . $login->getStatus() . '  ';//Logger::login();}}class mail extends LoginObserver{public function doUpdate(Login $login){echo __CLASS__ . ':' . $login->getStatus() . '  ';//Mailer::login();}}$login = new Login();new log($login);new mail($login);$login->notify();