一、什么是观察者模式
被观察者发生改变时,通知观察者。
代码实现:见我的github:观察者模式学习笔记
二、存在场景
ATM:你到ATM 机器上取钱,多次输错密码,卡就会被ATM吞掉,吞卡动作发生的时候,会触发哪些事件呢?第一摄像头连续快拍,第二,通知监控系统,吞卡发生;第三,初始化ATM 机屏幕,返回最初状态。你不能因为就吞了一张卡,整个ATM 都不能用了吧,一般前两个动作都是通过观察者模式来完成的。
广播链的问题:如果你做过数据库的触发器,你就应该知道有一个触发器链的问题,比如表A 上写了一个触发器,内容是一个字段更新后更新表B 的一条数据,而表B 上也有个触发器,要更新表C,表C 也有触发器…,完蛋了,这个数据库基本上就毁掉了!我们的观察者模式也是一样的问题,一个观察者可以有双重身份,即使观察者,也是被观察者,这没什么问题呀,但是链一旦建立,这个逻辑就比较复杂,可维护性非常差,根据经验建议,在一个观察者模式中最多出现一个对象既是观察者也是被观察者,也就是说消息最多转发一次(传递两次),这还是比较好控制的。
异步处理问题:这个EJB 是一个非常好的例子,被观察者发生动作了,观察者要做出回应,如果观察者比较多,而且处理时间比较长怎么办?那就用异步呗,异步处理就要考虑线程安全和队列的问题,这个大家有时间看看Message Queue,就会有更深的了解。
三、设计思路
主要主体:观察者和被观察者
观察者:第一步:修改flag/change:表示被观察者发生变化:super.setChanged();
第二步:通知其他观察者已经发生变化:
(1)传入变化信息:参数;super.notifyObservers("AnimalObservable eat");
(2)创建本地观察者的快照;Object[] arrLocal;
(3)加锁;synchronized (this)
(4)状态判断,并执行操作;for (int i = arrLocal.length-1; i>=0; i--) ((Observer)arrLocal[i]).update(this, arg);
被观察者:update方法执行被通知后操作
四、相关延伸: