观察者模式

观察者模式,又叫发布-订阅(Publish/Subscribe)模式,它定义了对象之间一对多的依赖关系,当一个对象状态改变时,其他相关联的对象就会得到通知并被自动更新。

例如,现有一组数据,分别画出柱状图、饼状图、折线图,当数据发生变化时,图形也需要同时进行相应的变化。

如图所示,监听的对象叫观察者(Observer),被监听的对象叫被观察者(Observable,也称主题Subject)。被观察者对象在状态上发生变化时,会通知所有观察者对象,使它们能够做出相应的变化。

观察者模式的实现方法可以有我们自己确定,Java也提供了对观察者模式的内置支持,java.util.Observable 类和 java.util.Observer 接口。虽然内置的方式不够灵活,有一些限制,但能够帮助我们理解和使用观察者模式。

Observer接口

public interface Observer {
    void update(Observable o, Object arg);
}

这个接口只定义了一个update()方法,当被观察者对象的状态发生变化时,这个方法就会被调用。

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

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

通过调用 addObserver 方法,将对象加入到列表中,setChanged 方法用来设置一个标记变量,代表被观察者对象的状态发生了变化,notifyObservers 方法被调用时,会调用所有添加的观察者的 update() 方法。


观察者模式示例

被观察者

public class Data extends Observable {
    private int[] array;

    public Data() {
        array = new int[20];
    }

    public void change(int position, int value) {
        array[position] = value;
        setChanged();
    }
}

观察者

public class Graph implements Observer{
    @Override
    public void update(Observable o, Object arg) {
        System.out.println("重新绘制数据!");
    }
}

测试

public class ObserverDemo {
    public static void main(String[] args) {
        Data data = new Data();
        Graph graph = new Graph();
        data.addObserver(graph);
        data.change(0, 1);
        data.notifyObservers();
    }
}

输出结果:

重新绘制数据!
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值