PHP模式设计----观察者模式(Observer)
PHP模式设计----观察者模式(Observer)
一、模式定义:
观察者模式有时也称为发布/订阅模式,是一种一对多的依赖关系,一旦主体对象状态发生改变,与之关联的观察者对象就会收到通知,然后做相应处理。
二、适用场景及优缺点:
当一个抽象模型有两个方面,其中一个方面依赖于另一个方面。
当对一个对象的改变需要同时改变其它对象,而不知道具体有多少个对象待改变。
当一个对象必须通知其它对象,而它又不能假定其它对象是谁。换句话说,你不希望这些对象是紧密耦合的。
当一个
观察者模式的优点:
1.观察者和主题之间的耦合度较小;
2.支持广播通信;
观察者模式的缺点:
由于观察者并不知道其它观察者的存在,它可能对改变目标的最终代价一无所知。这可能会引起意外的更新。
三、实现流程:
UML类图:
主体提供接口:注册、通知、解除注册等。
观察者提供接口:相应的业务处理。
观察者利用主题注册函数进行注册,主体数据发生改变,通过通知接口调用观察者的业务处理接口。
PHP为观察者模式定义了两个接口:SplSubject和SplObserver。SplSbuject可以看做主体对象的抽象,
SplObserver可以看做观察者对象的抽象,要实现观察者模式,只需要让主体对象实现SplSubject,观察者对象实现SplObserver,
并实现相应方法即可。
三、实例分析:
主体代码:Test.php
namespace App\Models;
use App\Models\TestObserver;
class Test implements \SplSubject{
protected $data = array();
public $property = 0;
/**
* observers
*
* @var \SplObjectStorage
*/
protected $observers;
public function __construct()
{
$this->observers = new \SplObjectStorage();
}
/**
* 添加观察者
*
* @param \SplObserver $observer
*
* @return void
*/
public function attach(\SplObserver $observer)
{
echo 'attach observer!';
$this->observers->attach($observer);
}
/**
* 取消观察者
*
* @param \SplObserver $observer
*
* @return void
*/
public function detach(\SplObserver $observer)
{
$this->observers->detach($observer);
}
/**
* 通知观察者方法
*
* @return void
*/
public function notify()
{
echo 'notify observer!';
/** @var \SplObserver $observer */
foreach ($this->observers as $observer) {
$observer->update($this);
}
}
/**
*
* @param string $name
* @param mixed $value
*
* @return void
*/
public function __set($name, $value)
{
$this->data[$name] = $value;
// 通知观察者用户被改变
$this->notify();
}
}
然后是观察者代码:TestObserver.php
namespace App\Models;
use App\Models\Test;
class TestObserver implements \SplObserver{
/**
* 观察者要实现的唯一方法
* 也是被 Subject 调用的方法
*
* @param \SplSubject $subject
*/
public function update(\SplSubject $subject)
{
echo get_class($subject) . ' has been updated';
echo $subject->property;
}
}
然后是个外部调用类:MyTest.php
namespace App\Models;
use Log;
use App\Cache\BaseCache;
use App\Models\Test;
use App\Models\TestObserver;
class MyTest{
protected $observer;
/**
* 测试通知
*/
public function testNotify()
{
echo "测试通知";
$subject = new Test();
$this->observer = new TestObserver();
$subject->attach($this->observer);
$subject->property = 123;
$subject->notify();
}
}
四、总结:主体和观察者的这种关系不是通过继承,而是通过组合,这样类之间的耦合性会低很多,同时一个主体也可以注册多个观察者。
以上内容参考自下面连接,为了便于理解在此记录。
原文参考:http://laravelacademy.org/post/2935.html
PHP模式设计----观察者模式(Observer)相关教程