事件驱动之JDK观察者模式
JDK中关于观察者模式主要了解俩个概念
- Observer观察者
- 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();
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());
/**
*源码解析
public synchronized void addObserver(Observer o) {
if (o == null)
throw new NullPointerException();
if (!obs.contains(o)) {
obs.addElement(o);
}
}
*/ paymentStatusObservable.updatePaymentStatus(1); } }
outPut:
更新支付状态为:1
更新订单事件源
邮件服务搜到通知...null