PHP面向对象深入理解之四(设计模式-观察者模式)
2017-08-29 21:03
1211 查看
观察者模式对于PHP而言,有几个内置的接口实现,相关的模式,分别是
SplSubject
SubObserver 和
SplObjectStoarge,相比uml类图,我比较喜欢用更通俗易懂的关系图解释现象,如下图。
被观察者 通过映射对象 存储了所有的 观察者对应的对象映射,然后在被观察者发生改变的时候,会循环映射对像,通知所有的观察者
,直接上代码。
主体(被观察者)类:
/**
* @package: 观察者模式
* 所谓的观察者,通俗一点讲
主体 (被观察者 A) SplSubject
存储容器 (观察者映射表) SplObjectStorage
观察者 B1,B2,B3... SplObserver
A一段发生改变,B1,B2,B3... 都会收到相应的通知
*/
//------------主体 被观察者
class Subject implements SplSubject
{
private $observers;
private $data;
public function setStorage()
{
$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 $observer){
$observer->update($this);
}
}
public function setData($data)
{
$this->data = $data;
}
public function getData()
{
return $this->data;
}
}
观察者:
//---------------观察者
//---------也就是说 每一个观察者 只要实现 SplObserver 并实现方法update 就能被通知到
class Observer implements SplObserver
{
private $name = '';
public function __construct($name)
{
$this->name = $name;
}
public function update(SplSubject $subject)
{
echo $this->name.":";
var_dump($subject->getData());
}
}
调用:
// 实例使用
$A = new Subject();
$A->setStorage();
$B1 = new Observer('B1');
$B2 = new Observer('B2');
$B3 = new Observer('B3');
$A->attach($B1);
$A->attach($B2);
$A->attach($B3);
$A->setData('123');
$A->notify();
$A->detach($B2);
$A->setData('456');
$A->notify();
调用结果:
B1:string(3) "123"
B2:string(3) "123"
B3:string(3) "123"
B1:string(3) "456"
B3:string(3) "456"
可以看到每个存在于映射对象里的对象都收到了相应的通知。其实具体的思路,我们不应该仅仅局限于
php所给的SplObjectStorage 存储,我们可以扩展到redis 及其他,SplSubject 和 SplObserver 也是,只要
实现 被观察者 能获取每一个观察者,并能调用相应的观察者通知方法,有点类似消息队列的定时推送,
SplSubject
SubObserver 和
SplObjectStoarge,相比uml类图,我比较喜欢用更通俗易懂的关系图解释现象,如下图。
被观察者 通过映射对象 存储了所有的 观察者对应的对象映射,然后在被观察者发生改变的时候,会循环映射对像,通知所有的观察者
,直接上代码。
主体(被观察者)类:
/**
* @package: 观察者模式
* 所谓的观察者,通俗一点讲
主体 (被观察者 A) SplSubject
存储容器 (观察者映射表) SplObjectStorage
观察者 B1,B2,B3... SplObserver
A一段发生改变,B1,B2,B3... 都会收到相应的通知
*/
//------------主体 被观察者
class Subject implements SplSubject
{
private $observers;
private $data;
public function setStorage()
{
$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 $observer){
$observer->update($this);
}
}
public function setData($data)
{
$this->data = $data;
}
public function getData()
{
return $this->data;
}
}
观察者:
//---------------观察者
//---------也就是说 每一个观察者 只要实现 SplObserver 并实现方法update 就能被通知到
class Observer implements SplObserver
{
private $name = '';
public function __construct($name)
{
$this->name = $name;
}
public function update(SplSubject $subject)
{
echo $this->name.":";
var_dump($subject->getData());
}
}
调用:
// 实例使用
$A = new Subject();
$A->setStorage();
$B1 = new Observer('B1');
$B2 = new Observer('B2');
$B3 = new Observer('B3');
$A->attach($B1);
$A->attach($B2);
$A->attach($B3);
$A->setData('123');
$A->notify();
$A->detach($B2);
$A->setData('456');
$A->notify();
调用结果:
B1:string(3) "123"
B2:string(3) "123"
B3:string(3) "123"
B1:string(3) "456"
B3:string(3) "456"
可以看到每个存在于映射对象里的对象都收到了相应的通知。其实具体的思路,我们不应该仅仅局限于
php所给的SplObjectStorage 存储,我们可以扩展到redis 及其他,SplSubject 和 SplObserver 也是,只要
实现 被观察者 能获取每一个观察者,并能调用相应的观察者通知方法,有点类似消息队列的定时推送,
相关文章推荐
- PHP面向对象深入理解之四(设计模式-工厂模式)
- PHP面向对象深入理解之四(设计模式-单例模式)
- 深入PHP面向对象、模式与实践——对象与设计
- 深入PHP面向对象、模式与实践——设计模式
- 深入理解PHP:高级技巧、面向对象与核心技术(原书第3版) -- 设计模式之组合模式
- PHP面向对象之旅:深入理解static变量与方法
- php部分---面向对象,设计模式(单例模式、工厂模式)、oop六大原则;
- 深入PHP面向对象、模式与实践——执行及描述任务(3)
- 深入PHP面向对象、模式与实践——高级特性(4)
- PHP面向对象深入理解之五(内省函数与反射类)
- 深入PHP面向对象、模式与实践——执行及描述任务(1)
- php设计模式之面向对象基础知识
- 深入理解JavaScript系列(32):设计模式之观察者模式
- 面向对象设计模式之一观察者模式
- 浅谈面向对象设计模式:观察者模式
- php面向对象深入理解(一)
- 设计模式-深入理解观察者模式
- 深入PHP面向对象、模式与实践
- PHP面向对象深入理解之二(封装、继承、多态、克隆)
- [.net 面向对象程序设计深入](31)实战设计模式——使用Ioc模式(控制反转或依赖注入)实现松散耦合设计(1)