一个简易的java自带的观察者模式实现

来源:互联网 发布:社交关系网络量化建模 编辑:程序博客网 时间:2024/06/05 12:10

      观察者模式是对象的行为模式,又叫发布-订阅(Publish/Subscribe)模式、模型-视图(Model/View)模式、源-监听器(Source/Listener)模式或从属者(Dependents)模式。

      观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态上发生变化时,会通知所有观察者对象,使它们能够自动更新自己。

JAVA提供的对观察者模式的支持

    在JAVA语言的java.util库里面,提供了一个Observable类以及一个Observer接口,构成JAVA语言对观察者模式的支持。
      

Observer接口

    这个接口只定义了一个方法,即update()方法,当被观察者对象的状态发生变化时,被观察者对象的notifyObservers()方法就会调用这一方法。
    
public interface Observer {    void update(Observable o, Object arg);}
       

Observable类

     被观察者类都是java.util.Observable类的子类。java.util.Observable提供公开的方法支持观察者对象,这些方法中有两个对Observable的子类非常重要:一个是setChanged(),另一个是notifyObservers()。第一方法setChanged()被调用之后会设置一个内部标记变量,代表被观察者对象的状态发生了变化。第二个是notifyObservers(),这个方法被调用时,会调用所有登记过的观察者对象的update()方法,使这些观察者对象可以更新自己。
    
public class Observable {    private boolean changed = false;    private Vector obs;       /** Construct an Observable with zero Observers. */    public Observable() {    obs = new Vector();    }    /**     * 将一个观察者添加到观察者聚集上面     */    public synchronized void addObserver(Observer o) {        if (o == null)            throw new NullPointerException();    if (!obs.contains(o)) {        obs.addElement(o);    }    }    /**     * 将一个观察者从观察者聚集上删除     */    public synchronized void deleteObserver(Observer o) {        obs.removeElement(o);    }    public void notifyObservers() {    notifyObservers(null);    }    /**     * 如果本对象有变化(那时hasChanged 方法会返回true)     * 调用本方法通知所有登记的观察者,即调用它们的update()方法     * 传入this和arg作为参数     */    public void notifyObservers(Object arg) {        Object[] arrLocal;    synchronized (this) {        if (!changed)                return;            arrLocal = obs.toArray();            clearChanged();        }        for (int i = arrLocal.length-1; i>=0; i--)            ((Observer)arrLocal[i]).update(this, arg);    }    /**     * 将观察者聚集清空     */    public synchronized void deleteObservers() {    obs.removeAllElements();    }    /**     * 将“已变化”设置为true     */    protected synchronized void setChanged() {    changed = true;    }    /**     * 将“已变化”重置为false     */    protected synchronized void clearChanged() {    changed = false;    }    /**     * 检测本对象是否已变化     */    public synchronized boolean hasChanged() {    return changed;    }    /**     * Returns the number of observers of this <tt>Observable</tt> object.     *     * @return  the number of observers of this object.     */    public synchronized int countObservers() {    return obs.size();    }}
         这个类代表一个被观察者对象,有时称之为主题对象。一个被观察者对象可以有数个观察者对象,每个观察者对象都是实现Observer接口的对象。在被观察者发生变化时,会调用Observable的notifyObservers()方法,此方法调用所有的具体观察者的update()方法,从而使所有的观察者都被通知更新自己。
         下面是我写的一个简单的观察者模式的实现,这里用milk表示牛奶订购者,模拟观察者对象Observer,用milkShop表示牛奶店,模拟被观察者对象(主题对象),模拟逻辑是牛奶订购者向牛奶店订购牛奶,当牛奶店有新的牛奶到货就通知订购者。
      
public class Milk implements Observer{public String Num;/* * update是Observer的实现方法arg1是subject传回的结果数据,这里可以主动获取,也可以获取数据为标志,然后再拉取   (non-Javadoc) * @see java.util.Observer#update(java.util.Observable, java.lang.Object) */    public void update(Observable arg0, Object arg1) {// TODO Auto-generated method stubNum=(String )arg1;System.out.println("********************"+Num);}}
  被观察者的代码如下
public class MilkShop extends Observable{public String Num;public String getNum() {return Num;}public void setNum(String num) {Num = num;DateChange();}/* * 数据变化,通知注册在他这里的观察者,并且把数据传给观察者 */     public void  DateChange(){        this.setChanged();    this.notifyObservers(Num);        }}
      测试类的代码如下
public class TestObserver {/** * @param args */public static void main(String[] args) {// TODO Auto-generated method stub              Milk mMilk=new Milk();              MilkShop mMilkShop=new MilkShop();              /*              * subject添加观察者,              */              mMilkShop.addObserver(mMilk);              /*               * 模拟subject数据变化,然后通知观察者数据变化,并且将数据传给观察者               */             mMilkShop.setNum("27");}}
   然后输出结果如下:





     
    


      

0 0