设计模式——观察者模式

观察者模式

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

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

模式结构

模式涉及角色

抽象被观察者:持有观察者的引用和被观察者状态标记,包括一些添加,删除,通知观察者的方法等。

抽象观察者:有一个回调 update 方法。

具体被观察者:对抽象被观察者的实现。

具体观察者:对抽象观察者的实现,回调 update 方法实现。

模式结构图

这里写图片描述
(图片来自网络,侵删)

示例

因为 Java 的 jdk 中已经有观察者模式的工具类,所以以 jdk 中的观察者模式为例。jdk 中已经定义好了被观察者类 Observable 和观察者接口 Observer。Observable 类中有记录状态属性和持有观察者引用的向量,然后是一些添加,删除,通知观察者的方法,值得注意的是只有被观察者对象的状态发生变化时,才会回调观察者的 update 方法,见方法 public void notifyObservers(Object arg) 实现代码。

代码实现

被观察者类 Observable

public class Observable {
    private boolean changed = false;
    //观察者的引用向量
    private Vector<Observer> obs;

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

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

        for (int i = arrLocal.length-1; i>=0; i--)
            ((Observer)arrLocal[i]).update(this, arg);
    }

    protected synchronized void setChanged() {
        changed = true;
    }

    //***其他方法就不在罗列了

观察者接口 Observer

public interface Observer {
    /**
     * This method is called whenever the observed object is changed. An
     * application calls an <tt>Observable</tt> object's
     * <code>notifyObservers</code> method to have all the object's
     * observers notified of the change.
     *
     * @param   o     the observable object.
     * @param   arg   an argument passed to the <code>notifyObservers</code>
     *                 method.
     */
    void update(Observable o, Object arg);
}

具体被观察者类 ConcreteObservable

/**
 * 具体被观察者
 */
class ConcreteObservable extends Observable{

    public ConcreteObservable(){
        super();
        setChanged();
    }

}

两个具体的观察者类 ConcreteObserver1,ConcreteObserver2


/**
 * 具体观察者
 */
class ConcreteObserver1 implements Observer{

    @Override
    public void update(Observable observable, Object object){
        System.out.println("观察者ConcreteObserver1 状态: " + object.toString());
    }
}

class ConcreteObserver2 implements Observer{

    @Override
    public void update(Observable observable, Object object){
        System.out.println("观察者ConcreteObserver2 状态: " + object.toString());
    }
}

测试代码

public class ObserverPattern {

    public static void main(String[] args){

        ConcreteObservable observable = new ConcreteObservable();
        ConcreteObserver1 concreteObserver1 = new ConcreteObserver1();
        ConcreteObserver2 concreteObserver2 = new ConcreteObserver2();
        observable.addObserver(concreteObserver1);
        observable.addObserver(concreteObserver2);

        observable.notifyObservers("状态发生变化,新状态是 ABC");

    }

}

其实看着这个代码很容易想起之前写的 Java——回调机制,其实观察者模式也是回调的一种实现,可以看到被观察者类 Observable 持有观察者引用的向量 private Vector<Observer> obs;,当被观察者状态发生变化时,会通过这些已经注册的观察者,回调观察者的 void update(Observable o, Object arg); 方法。

示例 demo 见:https://github.com/lzx2011/java-scaffold

运行结果

观察者ConcreteObserver2 状态: 状态发生变化,新状态是 ABC
观察者ConcreteObserver1 状态: 状态发生变化,新状态是 ABC

应用场景

当一个对象改变时,同时需要改变其他对象,应考虑使用观察者模式。  
  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值