您的位置:首页 > 其它

设计模式之行为型模式―― 3.2 观察者模式

2015-02-17 20:17 337 查看
<?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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: