系列文描述:

  该文章是日常笔记系列的第二篇,此乃第一节,主要记录了开发中如何基于Java使用观察者模式,相信看完肯定有所收获。

基于Java实现观察者模式

作用描述:

在日常研发过程总会遇见业务A随着业务B发生相关变化的情况,这种情况便可以运用观察者模式,而对于观察者模式,Java已经为我们提供了已有的接口和类方便我们使用。

对于订阅者Java为我们提供了一个接口,JDK源码如下:

public interface Observer {
        void update(Observable var1, Object var2);
    }
复制代码

可以看出,此处仅提供一个update方法用于接收通知者的通知做出相应改变。 在实际业务中,实现观察者模式的订阅者只需要实现该接口并实现update接口实现业务即可。

场景代码如下:


再来看看Java提供了一个怎样的通知者,可以看到JDK源码如下:

public class Observable {
    private boolean changed = false;
    //  存放Observer的容器,本身是安全的,看了源码,内部实现的大部分函数都使用了synchronized
    private Vector<Observer> obs = new Vector();

    public Observable() {
    }
    // 为通知者添加订阅者的地方
    public synchronized void addObserver(Observer var1) {
        if (var1 == null) {
            throw new NullPointerException();
        } else {
            if (!this.obs.contains(var1)) {
                this.obs.addElement(var1);
            }

        }
    }

    public synchronized void deleteObserver(Observer var1) {
        this.obs.removeElement(var1);
    }

    public void notifyObservers() {
        this.notifyObservers((Object)null);
    }

    public void notifyObservers(Object var1) {
        Object[] var2;
        synchronized(this) {
            if (!this.changed) {
                return;
            }

            var2 = this.obs.toArray();
            this.clearChanged();
        }

        for(int var3 = var2.length - 1; var3 >= 0; --var3) {
            ((Observer)var2[var3]).update(this, var1);
        }

    }

    public synchronized void deleteObservers() {
        this.obs.removeAllElements();
    }

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

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

    public synchronized boolean hasChanged() {
        return this.changed;
    }

    public synchronized int countObservers() {
        return this.obs.size();
    }
}
复制代码

首先我们可以从源码中看出Observable类使用Vector,Vector相比于ArrayList来说,它是线程安全的。其次,在多个函数上使用了synchronized关键字,这都是在为多线程考虑,避免出现在需要做出通知订阅者动作的时候因为数据紊乱出错的问题。 在实际业务中,直接继承该类即可,场景代码如下:


那么如何给监听者注册订阅者呢?场景代码如下:


而监听者通知订阅者的操作如下:


可以从上看出直接调用addObserver便可以给监听者注册订阅者,而在监听者发生变化的时候监听者调用setChange修改状态,之后调用notifyObservers通知,订阅者中的update实现便会被触发。

结尾说点什么

说好的一周一篇,上个周末沉迷docker的使用导致废了,然后最近又是每天都是差不多十二点下班,所以只能下班后花时间写总结最近的笔记了(  ̄▽ ̄)((≧︶≦)