-
观察者模式(Observer),当一个对象的状态发生改变时,依赖他的对象会全部收到通知,并自动更新。
-
场景:一个事件发生后,要执行一连串更新操作.传统的编程方式,就是在事件的代码之后直接加入处理逻辑,当更新得逻辑增多之后,代码会变得难以维护.这种方式是耦合的,侵入式的,增加新的逻辑需要改变事件主题的代码
观察者模式实现了低耦合,非侵入式的通知与更新机制 -
案例
/**
* 观察者接口类
* Interface ExceptionObserver
*/
interface ExceptionObserver {
public function update(Observable_Exception $e);
}
/**
* 事件产生类
* Class Observable_Exception
*/
class Observable_Exception extends Exception
{
public static $_observers = array();
//增加观察者
public static function attach(ExceptionObserver $observer)
{
self::$_observers[] = $observer;
}
public function __construct($message = null, $code = 0)
{
parent::__construct($message, $code);
$this->notify();
}
//事件通知
public function notify()
{
foreach(self::$_observers as $observer){
$observer->update($this);
}
}
}
//观察者(可以定义多个观察者)
class Logging_Exception_Observer implements ExceptionObserver
{
protected $_filename = '/Users/myl/www/log/logging.log';
public function __construct($filename = null)
{
if ($filename !== null && is_string($filename)) {
$this->_filename = $filename;
}
}
public function update(Observable_Exception $e)
{
// TODO: Implement update() method.
$message = "时间:" . date("Y-m-d H:i:s") . PHP_EOL;
$message .= "信息:" . $e->getMessage() . PHP_EOL;
$message .= "追踪信息:" . $e->getTraceAsString() . PHP_EOL;
$message .= "文件:" . $e->getFile() . PHP_EOL;
error_log($message, 3, $this->_filename);
}
}
//test.php
<?php
require_once "ExceptionObserver.php";
require_once "Observable_Exception.php";
require_once "Logging_Exception_Observer.php";
Observable_Exception::attach(new Logging_Exception_Observer());
Observable_Exception::attach(new Logging_Exception_Observer("/Users/myl/www/log/test1.log"));
class MyException extends Observable_Exception{
public function test(){
echo "this is a test ";
}
public function test1(){
echo '我是自定义的';
}
}
try{
throw new MyException("出现异常了");
} catch (MyException $e){
echo $e->getMessage();
echo "<hr/>";
$e->test();
echo "<hr/>";
$e->test1();
}