Java

it2022-05-05  89

原文地址: 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操作也会越来越慢。

转载于:https://www.cnblogs.com/robertsun/p/5212360.html

相关资源:Java观察者设计模式(Observable和Observer)

最新回复(0)