标签:设计模式 观察者模式
<?php /** * 3.2 观察者模式 * 定义: * 它定义了一种一对多的依赖关系,让多个观察者 * 对象同时监听某一个主题对象(通知者)。这个 * 主题对象在状态发生变化时,会通知所有观察者 * 对象,使它们能够自动更新自己。 * 角色: * 1. 抽象通知者 * 职责:它把所有对观察者对象的引用保存在 * 一个聚集里,每个通知者都可以有任 * 何数量的观察者,抽象通知者提供一 * 个接口,可以增加和删除观察者对象。 * 2. 具体通知者 * 职责:具体通知者,将有关状态存入具体观 * 察者对象;在具体通知者的内部状态 * 改变时,给所有登记过的观察者发出 * 通知。 * 3. 抽象观察者 * 职责:为所有具体观察者定义一个接口,在 * 得到通知者的通知时更新自己。 * 4. 具体观察者 * 职责:实现抽象观察者角色所要求的更新接 * 口,以便使本身的状态与通知者的状 * 态相协调。 * * 优点: * 1. 当两个对象之间送耦合,他们依然可以交互, * 但是不太清楚彼此的细节。观察者模式提供了 * 一种对象设计,让主题和观察者之间送耦合。 * 主题所知道只是一个具体的观察者列表,每一 * 个具体观察者都符合一个抽象观察者的接口。 * 主题并不认识任何一个具体的观察者,它只知 * 道他们都有一个共同的接口。 * 2. 观察者模式支持“广播通信”。主题会向所有的 * 观察者发出通知。 * 3. 观察者模式符合“开闭原则”的要求。 * * 缺点: * 1. 如果一个被观察者对象有很多的直接和间接的 * 观察者的话,将所有的观察者都通知到会花费 * 很多时间。 * 2. 如果在观察者和观察目标之间有循环依赖的话 * ,观察目标会触发它们之间进 行循环调用, * 可能导致系统崩溃。 * 3. 观察者模式没有相应的机制让观察者知道所观 * 察的目标对象是怎么发生变化的,而仅仅只是 * 知道观察目标发生了变化。 * * 使用场景: * 1. 一个抽象模型有两个方面,其中一个方面依赖 * 于另一个方面。将这些方面封装在独立的对象 * 中使它们可以各自独立地改变和复用。 * 2. 一个对象的改变将导致其他一个或多个对象也 * 发生改变,而不知道具体有多少对象将发生改 * 变,可以降低对象之间的耦合度。 * 3. 一个对象必须通知其他对象,而并不知道这些 * 对象是谁。需要在系统中创建一个触发链,A对 * 象的行为将影响B对象,B对象的行为将影响C对 * 象…,可以使用观察者模式创建一种链式触发机 * 制。 * */ //抽象通知者 abstract class Subject{ abstract public function attach(Observer $observer); abstract public function detach(Observer $observer); abstract public function notify(); abstract public function getState(); abstract public function setState($state); } //具体通知者 //注:如果有多个通知者,那么可以将公共的方法在抽象 // 通知者中实现。 class ConcreteSubject extends Subject{ private $obsvs=array(); private $state=‘‘; public function attach(Observer $observer){ if(! in_array($observer, $this->obsvs)){ $this->obsvs[]=$observer; } } public function detach(Observer $observer){ if(in_array($observer, $this->obsvs)){ $pos=array_search($observer, $this->obsvs); unset($this->obsvs[$pos]); } } public function notify(){ foreach ($this->obsvs as $observer) { $observer->update(); } } public function getState(){ return $this->state; } public function setState($state){ $this->state=$state; } } //抽象观察者 abstract class Observer{ protected $name; protected $sub; public function __construct($name,Subject $sub){ $this->name=$name; $this->sub=$sub; } abstract public function update(); } //具体观察者 class ConcreteObserver extends Observer{ public function update(){ echo $this->sub->getState().‘,‘.$this->name.‘快点关闭游戏,继续工作!‘; } } //客户端 $notify1=new ConcreteSubject(); $observer1=new ConcreteObserver(‘张三‘,$notify1); $observer2=new ConcreteObserver(‘李四‘,$notify1); //将通知对象(即观察者)放入通知列表中 $notify1->attach($observer1); $notify1->attach($observer2); $notify1->detach($observer2); //状态发生改变,观察者得到相应的状态通知后,做出 //相应的动作。 $notify1->setState(‘老板回来了‘); $notify1->notify(); ?>
本文出自 “一切皆有可能” 博客,请务必保留此出处http://noican.blog.51cto.com/4081966/1614784
标签:设计模式 观察者模式
原文地址:http://noican.blog.51cto.com/4081966/1614784