【观察者模式中主要角色】
1.抽象主题(Subject)角色:主题角色将所有对观察者对象的引用保存在一个集合中,每个主题可以有任意多个观察者。 抽象主题提供了增加和删除观察者对象的接口。
2.抽象观察者(Observer)角色:为所有的具体观察者定义一个接口,在观察的主题发生改变时更新自己。
3.具体主题(ConcreteSubject)角色:存储相关状态到具体观察者对象,当具体主题的内部状态改变时,给所有登记过的观察者发出通知。具体主题角色通常用一个具体子类实现。
4.具体观察者(ConcretedObserver)角色:存储一个具体主题对象,存储相关状态,实现抽象观察者角色所要求的更新接口,以使得其自身状态和主题的状态保持一致。
【观察者模式的优点和缺点】
观察者模式的优点:
1.观察者和主题之间的耦合度较小;
2.支持广播通信;
观察者模式的缺点:
由于观察者并不知道其它观察者的存在,它可能对改变目标的最终代价一无所知。这可能会引起意外的更新。
【观察者模式适用场景】
当一个抽象模型有两个方面,其中一个方面依赖于另一个方面。
当对一个对象的改变需要同时改变其它对象,而不知道具体有多少个对象待改变。
当一个对象必须通知其它对象,而它又不能假定其它对象是谁。换句话说,你不希望这些对象是紧密耦合的。
示例代码如下:
<?php header("content-type:text/html;charset=utf8"); /** * 先定义观察者模式需要的角色 * 目标 subject * ConcreteSubject: 具体目标 * Observer: 观察者 * ConcreteObserver: 具体观察者 */ //定义一个目标接口,目标要实现的方法,先抽象一个SUBJECT abstract class Subject{ //添加观察者 abstract function attach($observer); //去除观察者 abstract function delete($observer); //满足条件通知所有观察者修改 abstract function notify(); //发起通知的条件 abstract function condition($num); } //具体观察目标是什么 class ConcreteSubject extends Subject{ //定义一个空的数组 private $observers=array(); //添加观察者 function attach($observer){ $this->observers[]=$observer; } //移除观察者 function delete($observer){ $key=array_search($observer,$this->observers); if($key !== false){ $this->observers[$key]; } } //通知所有观察者修改 function notify(){ foreach ($this->observers as $observer ) { $observer->update(); } } //发起通知事件 function condition($num){ if($num=="老板回来了"){ $this->notify(); } } } //抽象观察者接口,定义所有观察者共同具有的属性——执行修改 abstract class Observer{ abstract function update(); } //具体观察者类,实现抽象观察者接口 class PeopleA extends observer{ function update(){ echo "A报告:boss咋这快回来了呢<br>"; } } class PeopleB extends observer{ function update(){ echo "B报告:俺还在吃东西呢<br>"; } } class PeopleC extends observer{ function update(){ echo "C报告:快快收拾<br>"; } } class PeopleD extends observer{ function update(){ echo "D报告:我还在看电影呢<br>"; } } class PeopleE extends observer{ function update(){ echo "E报告:快跑,<br>"; } } //输出 $a= new PeopleA(); $b= new PeopleB(); $c= new PeopleC(); $d= new PeopleD(); $e= new PeopleE(); $co= new ConcreteSubject(); $co->attach($a); $co->attach($b); $co->attach($c); $co->attach($d); $co->attach($e); $co->condition("老板回来了"); ?>