若转载教程,请注明出自SW-X框架官方文档1
<?php/*** 设计模式之观察者模式* 使用场景 订阅信息,消息推送* 小黄牛*/header("Content-type: text/html; charset=utf-8");/**** 抽象出通知者类*/abstract class Subject{private $observers = array(); // 用户保存观察成员# 添加观察成员public function Attach($observer){array_push($this->observers, $observer);}# 删除观察成员public function Detach($observer){foreach($this->observers as $k=>$v) {if($v==$observer) {unset($this->observers[$k]);}}}# 向观察成员群发消息function Notify(){foreach($this->observers as $v) {$v->Update();}}}//具体通知者(Boss和Secretary)class ConcreteSubject extends Subject{public $subject_state; // 推送的内容}//抽象观察者abstract class Observer{public abstract function Update();}//具体观察者class ConcreteObserver extends Observer{private $name; // 观察者名称private $observerState; // 保存通知者推送过来的内容public $subject; // 通知者实例,作用是保证大家都在同一频道内# 初始化成员属性public function __construct($_sub,$_name){$this->subject = $_sub;$this->name = $_name;}# 输出推送的内容public function Update(){$this->observerState = $this->subject->subject_state;echo "观察者:" .$this->name. "接受到的内容是:" .$this->observerState. "<br/>";}}# 实例化一个频道$A = new ConcreteSubject();# 添加两个观察者 - 并加入同一频道$zs = new ConcreteObserver($A, '张三');$ls = new ConcreteObserver($A, '李四');# 让两个观察者获得接受数据推送的权限$A->Attach($zs);$A->Attach($ls);# 注入推送内容$A->subject_state = "I Love You 小黄牛!";# 推送消息$A->Notify();
浏览器输出
观察者:张三接受到的内容是:I Love You 小黄牛!观察者:李四接受到的内容是:I Love You 小黄牛!
观察者模式
抽象通知者角色(INotifier):定义了通知的接口规则。具体通知者角色(Boss):实现抽象通知者的接口,接到状态改变立即向观察者下发通知。抽象观察者角色(IObserver):定义接到通知后所做的操作(Update)接口规则。具体观察者角色(JingDong):实现具体操作方法。
应用场景
订阅信息,消息推送
优点
1、一个抽象模型有两个方面,其中一个方面依赖于另一个方面。将这些方面封装在独立的对象中使它们可以各自独立地改变和复用。2、一个对象的改变将导致其他一个或多个对象也发生改变,而不知道具体有多少对象将发生改变,可以降低对象之间的耦合度。3、一个对象必须通知其他对象,而并不知道这些对象是谁。需要在系统中创建一个触发链,A对象的行为将影响B对象,B对象的行为将影响C对象……,可以使用观察者模式创建一种链式触发机制。
