观察者模式

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了观察者模式相关的知识,希望对你有一定的参考价值。

观察者模式定义:定义一种一对多对依赖关系,使得当一个对象状态改变,则所有依赖于它的对象都会得到通知并被自动更新。

举个栗子:夜里猫叫一声,家里的老鼠撒腿就跑,同时人也被吵醒了。

这个场景中,猫可看作是"被观察者",老鼠和人可看作是"观察者"。

代码清单-1 动物叫的接口

public interface AnimalCall {
    /**
     * 动物的叫声
     */
    void call();
}

代码清单-2  被观察者-猫

public class Cat extends Observable implements AnimalCall{

    public void call() {
        String msg = "喵呜喵呜...";
        System.out.println(msg);
        /* 打开通知开关 */
        super.setChanged();
        /* 通知观察者(老鼠,人)*/
        notifyObservers(msg);
    }
}

Observable是java.util包里提供的工具类,源码如下

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) {
            /*更新前,setChange(); */
            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();
    }
    
    protected synchronized void setChanged() {
        changed = true;
    }

    protected synchronized void clearChanged() {
        changed = false;
    }

    public synchronized boolean hasChanged() {
        return changed;
    }

    public synchronized int countObservers() {
        return obs.size();
    }
}

代码清单-3 观察者-老鼠

public class Mouse implements Observer {
    /* Observable类的方法notifyObservers里调用以下update */
    public void update(Observable o, Object msg) {
        System.out.println("mouse accept cat‘msg : "+ msg.toString());
        /* 触发跑的动作*/
        run();
    }

    public void run(){
        System.out.println("冤家来了,快跑!");
    }
}

代码清单-4 观察者-人

public class Person implements Observer {
    /* Observable类的方法notifyObservers里调用以下update */
    public void update(Observable o, Object msg) {
        System.out.println("person accept cat‘msg :" + msg.toString());
        /* 触发wake动作*/
        wake();
    }

    public void wake(){
        System.out.println("该死的猫,搅了我的美梦!");
    }
}

观察者老鼠和人都实现了java.util.observer接口,在update方法里执行具体的动作,如run, wake动作。update方法是由被观察类cat的父类Observable类的方法notifyObservers里调用的。

代码清单-5 场景类

public class Client {
    public static void main(String[] args){
        Observer mouse = new Mouse();
        Observer person = new Person();
        Cat cat = new Cat();
        cat.addObserver(mouse);
        cat.addObserver(person);
        cat.call();
    }
}

 

以上是关于观察者模式的主要内容,如果未能解决你的问题,请参考以下文章

未调用 LiveData 观察者

Java设计模式补充:回调模式事件监听器模式观察者模式(转)

如何为片段设置观察者

永远观察实时数据的片段

设计模式观察者模式 ( 简介 | 适用场景 | 优缺点 | 代码示例 )

观察者模式