1.定义
定义对象之间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖它的对象都会得到通知并自动更新
观察者模式也叫发布订阅模式
2.观察者模式的使用场景
相信大家都看过无间道,那么应该对我下面抽象的土匪在警局里面安插卧底的代码不会陌生,这就非常形象地描述了观察者模式。
package _16ObserverPattern; import java.util.ArrayList; import java.util.List; /** * 抽象被观察者 */ public abstract class Observable { // 存放所有观察者 private List<Observer> observers = new ArrayList<Observer>(); // 增加观察者 public void addObserver(Observer observer) { this.observers.add(observer); } // 删除观察者 public void deleteObserver(Observer observer) { this.observers.remove(observer); } // 通知每个观察者 public void notifyObserver(String context) { for(Observer observer : observers) { observer.update(context); } } }
package _16ObserverPattern; /** * 抽象观察者 */ public abstract class Observer { public abstract void update(String context); }
package _16ObserverPattern; /** * 具体被观察者 */ public class Police extends Observable { public void action() { System.out.println("警察出动了"); // 被卧底知道,通知大哥 notifyObserver("警察出动,大哥快走"); } }
package _16ObserverPattern; /** * 具体观察者 */ public class Bandit extends Observer { @Override public void update(String context) { System.out.println("土匪收到消息:"+context+"。马上闪"); } }
package _16ObserverPattern; /** * 场景类 */ public class Test { public static void main(String[] args) { // 一个警察 Police police = new Police(); // 一个土匪卧底在警局 Bandit bandit = new Bandit(); police.addObserver(bandit); // 警察行动 police.action(); // 结果又卧底,消息泄露,土匪全跑了 } }
你执行以下就会发现,警察一出动,土匪全跑了。这就是观察者模式,简单吧。
其实在Java中已经有观察者和被观察者的抽象实现,分别是java.util.Observer接口和java.util.Observable抽象类,可以替代我们上面的实现。
3.观察者模式的四个角色
4.观察者模式的优点
5.观察者模式的缺点
观察者模式需要考虑一下开发效率和运行效率的问题,一个被观察者,多个观察者,开发和调试就会比较复杂,而且在Java中的消息通知默认是顺序执行,一个观察者卡壳,会影响整体的执行效率。在这种情况下,一般考虑采用异步(多线程)实现。多级触发的效率也比较低,设计时应注意。
6.观察者模式的注意事项
7.现实世界的观察者模式