事件驱动之JDK观察者模式

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();



 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

 

 

 

posted @ 2018-07-31 18:26  陶朱公Boy  阅读(197)  评论(0编辑  收藏  举报