原文地址: Java_观察者模式(Observable和Observer)

一、观察者模式介绍
    在Java中通过Observable类和Observer接口实现了观察者模式。一个Observer对象监视着一个Observable对象的变化,当Observable对象发生变化时,Observer得到通知,就可以进行相应的工作
    如果画面A是显示数据库里面的数据,而画面B修改了数据库里面的数据,那么这时候画面A就要重新Load。这时候就可以用到观察者模
二、观察者模式实现方法
    java.util.Observable中有两个方法对Observer特别重要
    ①setChanged()方法
        /**
         * Sets the changed flag for this {@code Observable}. After calling
         * {@code setChanged()}, {@code hasChanged()} will return {@code true}.
         */  
        protected void setChanged() {  
            changed = true;  
        }

②notifyObservers()方法 / notifyObservers(Object data)方法
        /**
         * If {@code hasChanged()} returns {@code true}, calls the {@code update()}
         * method for every observer in the list of observers using null as the
         * argument. Afterwards, calls {@code clearChanged()}.
         * <p>
         * Equivalent to calling {@code notifyObservers(null)}.
         */  
        public void notifyObservers() {  
            notifyObservers(null);  
        }  
          
        /**
         * If {@code hasChanged()} returns {@code true}, calls the {@code update()}
         * method for every Observer in the list of observers using the specified
         * argument. Afterwards calls {@code clearChanged()}.
         *
         * @param data
         *            the argument passed to {@code update()}.
         */  
        @SuppressWarnings("unchecked")  
        public void notifyObservers(Object data) {  
            int size = 0;  
            Observer[] arrays = null;  
            synchronized (this) {  
                if (hasChanged()) {  
                    clearChanged();  
                    size = observers.size();  
                    arrays = new Observer[size];  
                    observers.toArray(arrays);  
                }  
            }  
            if (arrays != null) {  
                for (Observer observer : arrays) {  
                    observer.update(this, data);  
                }  
            }  
        }  
    以上两个方法十分重要
    setChanged()方法 ——
        用来设置一个内部标志位注明数据发生了变化
    notifyObservers()方法 / notifyObservers(Object data)方法 ——
        通知所有的Observer数据发生了变化,这时所有的Observer会自动调用复写好的update(Observable observable, Object data)方法来做一些处理(比如说画面数据的更新)。
        我们可以看到通知Observer有两个方法,一个无参,一个有参。那么这个参数有什么作用呢?
        其中一个作用:现在我不想通知所有的Observer,而只想其中一个指定的Observer做一些处理,那么就可以传一个参数作为ID,然后在所有的Observer中判断,每个Observer判断只有接收到底参数ID是属于自己的才做一些处理。
        当然参数还有其他作用,我只是举了个例子。
    下面举个例子加以说明:
        import java.util.Observable;    
        /**
         * 被观察者类
         */      
        public class SimpleObservable extends Observable    
        {    
           private int data = 0;
           
           public int getData(){     
               return data;    
           }    
              
           public void setData(int i){    
               if(this.data != i) {   
                  this.data = i;   
                  setChanged();    
          
                  //只有在setChange()被调用后,notifyObservers()才会去调用update(),否则什么都不干。  
                  notifyObservers();      
               }    
           }    
        }

上面这个类是一个被观察者类,它继承了Observable类,表示这个类是可以被观察的。
    然后在setData()方法里面,也就是数据改变的地方,来调用Observable类的setChanged()方法和notifyObservers()方法,表示数据已改变并通知所有的Observer调用它们的update()方法做一些处理。
    注意:只有在setChange()被调用后,notifyObservers()才会去调用update(),否则什么都不干。
          /**
         * 观察者类
         */        
        public class SimpleObserver implements Observer    
        {    
           public SimpleObserver(SimpleObservable simpleObservable){    
              simpleObservable.addObserver(this );    
           }    
              
           public void update(Observable observable ,Object data){  // data为任意对象,用于传递参数  
              System.out.println(“Data has changed to” + (SimpleObservable)observable.getData());    
           }    
        }

通过生成被观察者(SimpleObservable类)的实例,来调用addObserver(this)方法让观察者(SimpleObserver类)达到观察被观察者(SimpleObservable类)的目的。
    然后还要复写update()方法,做数据改变后的一些处理。
    下面可以写一个简单的测试类来测试一下
        public class SimpleTest    
        {    
           public static void main(String[] args){    
              SimpleObservable doc = new SimpleObservable ();    
              SimpleObserver view = new SimpleObserver (doc);    
              doc.setData(1);    
              doc.setData(2);    
              doc.setData(2);    
              doc.setData(3);     
           }    
        }   
    运行结果如下
    [plain] view plain copy
        Data has changed to 1   
        Data has changed to 2  //第二次setData(2)时由于没有setChange,所以update没被调用  
        Data has changed to 3  
    下面介绍一个Observable类的其他一些属性和方法
    属性 ——
        // observers是一个List,保存着所有要通知的observer。      
        List<Observer> observers = new ArrayList<Observer>();  
        // changed是一个boolean型标志位,标志着数据是否改变了。  
        boolean changed = false;

方法 ——
        // 添加一个Observer到列表observers中  
        public void addObserver(Observer observer) {  
            if (observer == null) {  
                throw new NullPointerException();  
            }  
            synchronized (this) {  
                if (!observers.contains(observer))  
                    observers.add(observer);  
            }  
        }  
          
        // 从列表observers中删除一个observer  
          
        public synchronized void deleteObserver(Observer observer) {  
            observers.remove(observer);  
        }  
          
        // 清空列表observers  
        public synchronized void deleteObservers() {  
            observers.clear();  
        }  
          
        // 返回列表observers中observer的个数  
          
        public int countObservers() {  
            return observers.size();  
        }  
          
          
        // 重置数据改变标志位为未改变  
        protected void clearChanged() {   
        changed = false;  
        }  
          
        // 将数据改变标志位设置为改变  
          
        protected void setChanged() {   
            changed = true;  
        }  
          
          
        // 判断标志位的值  
        public boolean hasChanged() {   
            return changed;  
        }  
          
        // 通知所有observer(无参)  
        public void notifyObservers() {  
            notifyObservers(null);  
        }  
        // 通知所有observer(有参)  
        @SuppressWarnings("unchecked")  
        public void notifyObservers(Object data) {   
            int size = 0;   
            Observer[] arrays = null;   
            synchronized (this) {   
                if (hasChanged()) {   
                    clearChanged();   
                    size = observers.size();  
                    arrays = new Observer[size];   
                    observers.toArray(arrays);   
                }   
            }   
            if (arrays != null) {   
                for (Observer observer : arrays) {   
                    observer.update(this, data);   
                }   
            }  
        }  
    注意:在Observer对象销毁前一定要用deleteObserver将其从列表中删除,也就是在onDestroy()方法中调用deleteObserver()方法。
    不然因为还存在对象引用的关系,Observer对象不会被垃圾收集,造成内存泄漏,并且已死的Observer仍会被通知到,有可能造成意料外的错误,而且随着列表越来越大,notifyObservers操作也会越来越慢。

Java_观察者模式(Observable和Observer) -转的更多相关文章

  1. java中观察者模式Observable和Observer

    25.java中观察者模式Observable和Observer 如果想要实现观察者模式,则必须依靠java.util包中提供的Observable类和Observer接口 观察者设计模式 现在很多的 ...

  2. 设计模式之观察者模式(Observable与Observer)

    设计模式之观察者模式(Observable与Observer) 好久没有写博客啦,之前看完了<设计模式之禅>也没有总结一下,现在回忆一下设计模式之观察者模式. 1.什么是观察者模式 简单情 ...

  3. 25、java中观察者模式Observable和Observer

    如果想要实现观察者模式,则必须依靠java.util包中提供的Observable类和Observer接口 观察者设计模式 现在很多的购房者都在关注着房子的价格变化,每当房子价格变化的时候,所有的购房 ...

  4. Java_观察者模式(Observable和Observer)

    http://blog.csdn.net/tianjf0514/article/details/7475164/ 一.观察者模式介绍 在Java中通过Observable类和Observer接口实现了 ...

  5. 十一、观察者模式(Observable、Observer)

    老板出差了,员工1.员工2..均放羊中.他们请求前台的秘书,当老板回来时通知自己,免得被Boss抓个现行.秘书想了想,说————嗯,这是观察者模式. 当一个对象的改变需要同时改变其它对象,而且它不知道 ...

  6. RxJava 设计理念 观察者模式 Observable lambdas MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  7. [RxJS] Subject: an Observable and Observer hybrid

    This lesson teaches you how a Subject is simply a hybrid of Observable and Observer which can act as ...

  8. OpenJDK源码研究笔记(六)--观察者模式工具类(Observer和Observable)和应用示例

    本文主要讲解OpenJDK观察者模式的2个工具类,java.util.Observer观察者接口,java.util.Observable被观察者基类. 然后,给出了一个常见的观察者应用示例. Obs ...

  9. Java常用类库--观察者设计模式( Observable类Observer接口)

    如果要想实现观察者模式,则必须依靠java.util包中提供的Observable类和Observer接口. import java.util.* ; class House extends Obse ...

随机推荐

  1. nodejs http.get乱码问题处理方法

    var req = http.get(url,function(res){ res.setEncoding('utf-8'); var html = '' res.on('data',function ...

  2. 网页通用的测试用例(出处:: 51Testing-- lxp1119216)

    此题的考察目的:面试者是否熟悉各种测试方法,是否有丰富的Web测试经验, 是否了解Web开发,以及设计Test case的能力 这个题目还是相当有难度的, 一般的人很难把这个题目回答好. 首先,你要了 ...

  3. Oracle数据库简介

    Oracle数据库简介 一.介绍 Oracle数据库系统是美国Oracle(甲骨文)公司提供的以分布式数据库为核心的一组软件产品,是目前最流行的客户/服务器(Client/Server,C/S)或浏览 ...

  4. Box model小心得

    最近在研究css~当设置一个元素width后~有时候也会对他设定padding,margin,border值, 每次这样我就心里琢磨,那这个元素的width会变吗,js获取元素的宽度width()指的 ...

  5. 记一次 nginx 504 Gateway Time-out

    今天程序在执行一项excel导出任务的时候 出现了nginx超时的提示 nginx 504 Gateway Time-out 排查过程: 查看该任务 发现内容是一个数据量20000条信息 每条信息有5 ...

  6. haslayout和BFC

    感谢CSS涛的分享,参考文章: (1)haslayout:http://aibusy.com/blog/?p=53 (2)BFC 神奇背后的原理:http://aibusy.com/blog/?p=8 ...

  7. CSS中常用中文字体转Unicode编码表

    中文名 英文名 Unicode Unicode 2 Mac OS 华文细黑 STHeiti Light [STXihei] \534E\6587\7EC6\9ED1 华文细黑 华文黑体 STHeiti ...

  8. php的header()函数前有echo输出情况分析

    php的header()方法一般被用来告知浏览器做一些什么样的操作,比如跳转,刷新等等:而调用header方法前,如果使用echo输出一些内容,会发生什么情况呢?会对header函数有影响吗?我们实验 ...

  9. echarts.制作中国地图,点击对应的省市链接到该省份的详细介绍

    今天花了一天的时间,用echart弄了一个效果,是从中国地图点进去身份并把改省份的数据渲染出来的效果,刚开始完全没有头绪,只能硬着头皮去看百度echart的api,和博客,看了半天,好家伙,终于给我找 ...

  10. sae Servlet class XXXX is not a javax.servlet.Servlet

    以前都是使用myeclipse开发web工程上传sae后没有问题,但是使用javaee导出war包上传sae 无法访问 Servlet class  XXXX is not a javax.servl ...