设计模式之皇后:观察者模式

来源:互联网 发布:思迅足浴软件 编辑:程序博客网 时间:2024/06/06 00:41
在描述观察者模式之前,先说说生活中的一个例子:ATM 机的吞卡现象。
但我们用银行卡在 ATM 机上进行交易时,若人品不佳,就有可能会出现吞卡这种悲剧的事情。当吞卡事件发生时,自助银行所装备的摄像头将连续狂拍,保留案发现场,同时,ATM 机将告知客户应采取的挽救措施,如拨打银行电话等,然后退出当前客户的操作并跳转至开始界面,等待下一位客户。
这一系列事件是如何发生的呢?大概可以猜想到,有两种实现的方式。其一,摄像头等物件一直在观察是否有吞卡发生,若果然发生了吞卡事件,则立马响应,做出狂拍等操作;其二,摄像头等物件不必时时对吞卡现象进行监控,而是反过来,当吞卡事件发生时,告知摄像头等物件,案发了,赶紧采取措施吧。对比这两种实现方式,明显可以看出,第一种方法消耗过大,而第二种方法则巧妙得多。
在程序设计中,如果有一个或多个对象 O1、O2...对另外的某个对象 O 产生了兴趣,需要在 O 的状态发生改变时做出相应的操作、修改自己的状态,同样有两种实现方式。一是 O1、O2...通过线程一直对 O 进行监视,当发现各自对 O 所感兴趣的部分发生改变时,做出自己的响应;二是 O 在自己的状态发生改变时,主动通知 O1、O2...:“我改变了,对我感兴趣的所有东东们,该干嘛就干嘛吧!”。相比之下,第一种方式中,或者每增加一个对 O 有兴趣的对象,就多加一个对应的线程来对 O 实现监控,根据此方法实现的程序性能可想而知;或者通过一个统一的线程来对 O 实现监控,但每增加一个对 O 有兴趣的对象,就得对该线程进行修改,如此实现完全不符合程序设计的闭开原则,维护困难。而第二种方式中,O 一个对象的辛劳取代了 O1、O2...没完没了的监控,这便是鼎鼎大名的观察着模式。
观察者模式定义来对象之间一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动更新。观察者模式包括两个主体:
1 观察者:即偷窥狂,发现自己感兴趣的对象状态改变了,自己也将做出回应
2 被观察者:即被观察的对象,如果该对象发生某些变化则通知观察者执行响应


如此,观察者模式的大概意思就阐述明白了,可是如何实现呢?这不是难事,但强大的 Java 从来不让我们失望,Java 对观察者模式提供了原生支持,方便无需解释!
1 观察者 接口:java.util.Observer,在实现观察者模式时,观察者只要实现该接口即可。
2 被观察者 类:java.util.Observable,在实现观察者模式时,被观察者只要认其为父即可。


下面是 java.util.Observer 和 java.util.Observable 的部分源代码:
java.util.Observable
public class Observable {    private boolean changed = false;    private Vector 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) {        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);    }}

java.util.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);}}

Java 能将观察者模式置入 java.util 中,可见观察者模式的地位之高,难怪其被称为“设计模式之皇后”。基于 Java 对观察者模式的原生支持,幸福的 Java 程序员在实现观察者模式时当易如反掌,各种事件处理手到擒来。
原创粉丝点击