zoukankan      html  css  js  c++  java
  • 事件驱动之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

     

     

     

  • 相关阅读:
    猴子得到一堆桃,当天吃了一半之后,又多吃了1个。以后每天,猴子都吃了剩余的一半桃子之>后,又多吃一个。在第10天,只剩下1个桃子。输出这堆桃最初有多少个。
    打印9 9乘法表
    尝试实现一个管理系统, 名字和电话号分别用两个列表存储 =======通讯录管理系统======= 1.增加姓名和手机 2.删除姓名 3.修改手机 4.查询所有用户 5.根据姓名查找手机号 6.退出
    求结果
    背景流动
    1
    zuoye
    假期 作业1220
    python1217作业
    pythonzuoye20181212
  • 原文地址:https://www.cnblogs.com/zhangfengshi/p/9397519.html
Copyright © 2011-2022 走看看