观察者模式(世界线的观测者)
定义
观察者模式(Observer Partern)也叫做发布/订阅模式(Publish/Subscribe),一种以监听为核心的设计模式。
定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并被自动更新。
优缺点、应用场景
优点
- 观察者和被观察者之间是抽象耦合。如此不论是增加观察者还是被观察者都非常容易拓展,而且都是Java中已经实现的抽象层级定义。
- 建立一套触发机制。蝴蝶效应,一举一动都会影响世界线的变动。
缺点
需要考虑开发和运行效率,一般会采用异步的方式。
应用场景
- 关联行为场景。关联行为是可拆分的,而不是耦合的“组合”关系
- 事件多级触发场景
- 跨系统的消息交换场景,如消息队列的上下游消息的传递。
代码模拟场景
战国时期秦国的丞相李斯想要监控韩非子的一举一动,于是安插间谍在韩非子周围
实验小结
- 将观察者嵌入到被观察者类中确实能够实现监控,但是不利于观察者的拓展
- 现需要两个接口Observer和Observable
- 前者是观察者实现的,需要重写update方法,决定监听到方法执行后的逻辑
- 后者是被观察者实现的,将所有参与观察的观察者封装成集合,执行方法时统一通知。
然后去欺骗世界吧,命运石之门必定存在,EL PSY CONGROO
观察者模式
UML图
观察者接口与实现类
/*** 观察者接口*/
public interface Observer {// 被观察者操作则通知public void update(String context);
}public class LiSi implements Observer {// 若韩非子有动向,立即知晓@Overridepublic void update(String context) {System.out.println("李斯:观察到韩非子活动,开始向上级汇报");this.reportToEmperor(context);System.out.println("李斯:汇报完毕。。\n");}private void reportToEmperor(String context) {System.out.println("李斯:报~~~!韩非子有活动了----->" + context);}
}/*** 张苍,同韩非子、李斯为荀子的弟子* 助刘邦统一,官至丞相*/
public class ZhangCang implements Observer {@Overridepublic void update(String context) {System.out.println("张苍:观察到韩非子活动,开始♂摸索");jieBroQuotation(context);System.out.println("张苍:摸索♂结束");}public void jieBroQuotation(String context) {System.out.println("张苍:韩非子有活动?让我康康!!------->" + context);}
}
被观察者接口及实现类
/*** 被观察者接口*/
public interface Observable {// 增加一个观察者public void addObserver(Observer observer);// 删除一个观察者public void deleteObserver(Observer observer);// 被观察者操作时,通知观察者public void notifyObservers(String context);
}
被观察者个性接口
/*** 被观察者接口*/
public interface IHanFeiZi {// 韩非子吃早餐public void haveBreakfast();// 韩非子玩♂游♂戏public void haveFun();
}public class HanFeiZi implements Observable,IHanFeiZi {// 所有的观察者放在一个集合中private List<Observer> observerList = new ArrayList<>();// 韩非子要吃饭了@Overridepublic void haveBreakfast() {System.out.println("韩非子:开始吃饭了。。。");this.notifyObservers("韩非子在吃饭");}// 韩非子要玩♂游♂戏了@Overridepublic void haveFun() {System.out.println("韩非子:玩♂游♂戏");this.notifyObservers("韩非子在玩♂游♂戏");}// 添加一个观察者@Overridepublic void addObserver(Observer observer) {this.observerList.add(observer);}// 删除一个观察者@Overridepublic void deleteObserver(Observer observer) {this.observerList.remove(observer);}// 通知观察者们@Overridepublic void notifyObservers(String context) {for (Observer observer : observerList) {observer.update(context);}}
}
入口类方法
public static void realObserve() {// 观察者阵容Observer liSi = new LiSi();Observer zhangCang = new ZhangCang();// 被观察者HanFeiZi hanFeiZi = new HanFeiZi();hanFeiZi.addObserver(liSi);hanFeiZi.addObserver(zhangCang);// 被观察者开始动作hanFeiZi.haveBreakfast();hanFeiZi.haveFun();
}
结果
参考书籍
秦小波《设计模式之禅》