JDK中关于观察者模式主要了解俩个概念

  1. Observer观察者
  2. Observable事件源;当事件源发生某事件时,有两个事情需要注意 1.里面有一个isChange属性  当为false时不会发通知给观察者。所以一般先setChange为true,然后注册观察者,再调用notifyObservers方法  通知所有观察者中的update方法

代码:

定义一个观察者:

public class EmailObserver implements Observer {

    @Override
public void update(Observable o, Object arg) {
if (o instanceof PaymentStatusObservable) {
System.out.println("更新订单事件源");
} System.out.println("邮件服务搜到通知..." + arg); } }

定义一个事件源

/**
*此类表示模型视图范例中的 observable 对象,或者说“数据”。可将其子类化,表示应用程序想要观察的对象。 一个 observable 对象可以有一个或多个观察者。观察者可以是实现了 Observer 接口的任意对象。一个 observable 实例改变后,调用 Observable 的 notifyObservers 方法的应用程序会通过调用观察者的 update 方法来通知观察者该实例发生了改变。 未指定发送通知的顺序。Observable 类中所提供的默认实现将按照其注册的重要性顺序来通知 Observers,但是子类可能改变此顺序,从而使用非固定顺序在单独的线程上发送通知,或者也可能保证其子类遵从其所选择的顺序。 注意,此通知机制与线程无关,并且与 Object 类的 wait 和 notify 机制完全独立。 新创建一个 observable 对象时,其观察者集是空的。当且仅当 equals 方法为两个观察者返回 true 时,才认为它们是相同的。<P> 注意点:
Observable实现了大部分的逻辑,没有很好地进行抽象,灵活性降低了 存在2个潜在的问题:一个刚刚加入的观察者错过了通知;一个刚刚删除的观察者被错误的通知 Observable实现的方法采用synchronized,操作同一个方法时串行,可能会存在效率问题 */
public class PaymentStatusObservable extends Observable { public void updatePaymentStatus(int status) {
System.out.println("更新支付状态为:" + status);
this.setChanged();
/**
* 如果 hasChanged 方法指示对象已改变,则通知其所有观察者,并调用 clearChanged 方法来指示此对象不再改变。
每个观察者都有其 update 方法,其调用参数有两个:observable 对象和 null。换句话说,此方法等效于: notifyObservers(null)
*/
this.notifyObservers();

p.p1 { margin: 0; font: 12px Menlo }
p.p2 { margin: 0; font: 12px Menlo; color: rgba(78, 144, 114, 1) }
p.p3 { margin: 0; font: 12px Menlo; min-height: 14px }
p.p4 { margin: 0; font: 12px Menlo; color: rgba(147, 26, 104, 1) }
span.s1 { color: rgba(147, 26, 104, 1) }
span.s2 { color: rgba(126, 80, 79, 1) }
span.s3 { color: rgba(78, 144, 114, 1) }
span.s4 { color: rgba(0, 0, 0, 1) }
span.s5 { color: rgba(3, 38, 204, 1) }


public void notifyObservers(Object arg) {


/*


* a temporary array buffer, used as a snapshot of the state of


* current Observers.


*/


Object[] arrLocal;



synchronized (this) {


/* We don't want the Observer doing callbacks into


* arbitrary code while holding its own Monitor.


* The code where we extract each Observable from


* the Vector and store the state of the Observer


* needs synchronization, but notifying observers


* does not (should not).  The worst result of any


* potential race-condition here is that:


* 1) a newly-added Observer will miss a


*   notification in progress


* 2) a recently unregistered Observer will be


*   wrongly notified when it doesn't care


*/


if (!changed)


return;


arrLocal = obs.toArray();//得到事先加入的vector的观察者


clearChanged();


}



for (int i = arrLocal.length-1; i>=0; i--)


((Observer)arrLocal[i]).update(this, arg);//更新观察者的update方法


}

} }

demo:

public class ClientDemo {

    public static void main(String[] args) {
// 被观察者。即事件源
PaymentStatusObservable paymentStatusObservable = new PaymentStatusObservable(); // 如果观察者与集合中已有的观察者不同,则向对象的观察者集中添加此观察者
paymentStatusObservable.addObserver(new EmailObserver());

/**
*源码解析

p.p1 { margin: 0; font: 12px Menlo }
span.s1 { color: rgba(147, 26, 104, 1) }
span.s2 { color: rgba(126, 80, 79, 1) }
span.s3 { color: rgba(3, 38, 204, 1) }


public synchronized void addObserver(Observer o) {


if (o == null)


throw new NullPointerException();


if (!obs.contains(o)) {


obs.addElement(o);


}


}


*/ paymentStatusObservable.updatePaymentStatus(1);
}
}

outPut:

p.p1 { margin: 0; font: 12px Menlo }

更新支付状态为:1

更新订单事件源

邮件服务搜到通知...null

最新文章

  1. 蚂蚁金服寒泉子:JVM源码分析之临门一脚的OutOfMemoryError完全解读
  2. CentOS6.3 编译安装LAMP(3):编译安装 MySQL5.5.25
  3. range for query
  4. DuiLib学习笔记1——编译运行demo
  5. 【Simplify Path】cpp
  6. Angularjs 如何在 post 请求时去掉因 ng-repeat 产生的 $$hashkey?
  7. Android Studio你不知道的调试技巧
  8. Gulp插件汇总
  9. php前端控制器2
  10. _tcscat在Debug和Release根据问题
  11. 其他应用和技巧-eval()函数大行其道
  12. iOS Learning
  13. 获取博客积分排名,存入数据库,读取数据进行绘图(python,selenium,matplotlib)
  14. BZOJ-1010-[HNOI2008]玩具装箱toy(斜率优化)
  15. VLAN之间单臂路由通信
  16. Golang的流程控制
  17. SQLPrompt 安装后sql上看不到菜单
  18. 287. Find the Duplicate Number 找出数组中的重复数字
  19. B - Internship (网络流关键割边)
  20. sklearn调参(验证曲线,可视化不同参数下交叉验证得分)

热门文章

  1. 基于struts2的记住账号密码的登录设计
  2. moviepy音视频开发:音频合成类CompositeAudioClip介绍
  3. 转:为什么说Python是最值得学习的编程语言
  4. PyQt学习随笔:Model/View开发时从Model相关类派生自定义类需要注意的问题
  5. 派大星的烦恼MISC
  6. 图论——迪杰斯特拉算法(Dijkstra)实现,leetcode
  7. 测试与发布( Alpha版本 )
  8. Devpress (DxReport)使用ReportDesigner (一) 基本功能
  9. Codeforces Edu Round 51 A-D
  10. PhotoSwipe用法