观察者模式
观察者模式完美的将观察者和被观察的对象分离开。 举个例子, 用户界面可以作为一个观察者,业务数据是被观察者,用户界面观察业务数据的变化,发现数据变化后,就显示在界面上。面向对象设计的一个原则是:系统中的每个类将重点放在某一个功能上,而不是其他方面。 一个对象只做一件事情, 并且将他做好。 观察者模式在模块之间划定了清晰的界限 ,提高了应用程序的可维护性和重用性。实现观察者模式有很多形式, 比较直观的一种是使用一种“注册——通知——撤销注册”的形式。
当管理员登录时,会自动发送邮件和记录到数据库,这两个就是观察者,而管理员登录就是被观察者。
$_login = new Login(); //被观察者 $_login->attach(new MailWarning());//注册发送邮件的观察者 $_logger = new Logger(); $_login->attach($_logger); //注册记录到数据库的观察者 echo $_login->handleLogin('admin', '123456'); //管理员登录
<?php //被观察者 abstract class Observable { abstract public function attach(Observer $_observer); //注册观察者 abstract public function detach(Observer $_observer); //撤销观察者 abstract public function notify(); //响应观察者 }
//被观察者Login class Login extends Observable { private $_user = 'admin'; private $_pass = '123456'; private $_ret; private $_info; private $_observers = array(); public function attach(Observer $_observer) { $this->_observers[] = $_observer; } public function detach(Observer $_observer) { if (in_array($_observer, $this->_observers)) { $this->_observers = array_udiff($this->_observers, array($_observer), create_function('$a,$b', 'return ($a === $b) ? 0:1;')); } } public function notify() { foreach ($this->_observers as $_obs) { $_obs->update($this); } } public function handleLogin($_user, $_pass) { $this->_info = array($_user, $_pass); switch ($this->check($this->_info)) { case 1 : $this->_ret = true; break; case 2 : $this->_ret = false; break; } $this->notify(); return $this->_ret; } private function check($_info) { if ($_info[0] == $this->_user && $_info[1] == $this->_pass) { return 1; } return 2; } public function getInfo() { return $this->_info; } public function getRet() { return $this->_ret; } } ?>
<?php //观察者类 abstract class Observer { abstract public function update(Observable $_observable); } ?> <?php class MailWarning extends Observer { public function update(Observable $_observable) { $_info = $_observable->getInfo(); $_ret = $_observable->getRet(); if (!$_ret) { echo '发送一封邮件给总管理员:用户名:'.$_info[0].',密码:'.$_info[1].'登录错误!'; } } } ?> <?php class Logger extends Observer { public function update(Observable $_observable) { $_info = $_observable->getInfo(); echo '写入数据库:用户名:'.$_info[0].',密码:'.$_info[1].'在某时某刻某地登录过!'; } } ?>
$_login->detach($_cookies); //注销观察者 $_login->detach($_logger); //注销观察者