标签:设计模式 观察者模式
<?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