0
点赞
收藏
分享

微信扫一扫

设计模式 - 观察者模式以及存在的问题

观察者模式 其实可以称之为发布订阅模型的 ,因为里面有一个Observable 和一个Observer , 我这个Observable为可以观察到的意思 , 意思就是对外可见的, 所以可以称之为发布者(publisher) , 其他的Observer可以称之为订阅者 (subscriber) ,是对外不可见的 .

1. JDK的观察者模式

 java.util.Observable 这个类和java.util.Observer这个类是一个JDK给我们提供的框架 , 我们分析一波

1. Observable

文章最前面已经介绍过了 , 所以就直接讲了, 他就是一个管理观察者的对象

设计模式 - 观察者模式以及存在的问题_观察者模式

我们看这张图, 主要是分为addObserver 方法 ,表示添加一个观察者 , 与之对应的就是deleteObserver 移除了,

还有就是notifyObservers 就是通知观察者了 , 其他的就不多说了 , 观察者通过一个Vector安全数组来维护 , 通知的时候遍历通知 ,

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

他存在的问题我们后续说 ,

2. 基于JDK接口去实现

发布者

public class MyObservable extends Observable {

    @Override
    protected synchronized void setChanged() {
        super.setChanged();
    }

    @Override
    public synchronized void addObserver(Observer o) {
        super.addObserver(o);
    }

    @Override
    public synchronized boolean hasChanged() {
        return super.hasChanged();
    }
}

订阅者

public class MyObserver implements Observer {

    private String name;

    public MyObserver(String name) {
        this.name = name;
    }

    @Override
    public void update(Observable o, Object arg) {
        System.out.println(this.name+" 收到消息 : "+arg);
    }
}

测试Demo

public class Demo {


    public static void main(String[] args) {
        MyObservable observable = new MyObservable();

        // 添加观察者
        observable.addObserver(new MyObserver("tom"));
        observable.addObserver(new MyObserver("tony"));

        // 必须修改, 不然没法通知到
        observable.setChanged();

        // 通知
        observable.notifyObservers("安星是个傻子");

    }
}

输出

tony 收到消息 : 安星是个傻子
tom 收到消息 : 安星是个傻子

3. 存在的问题

我们发现所有的观察者都没有主动权, (这里的意思是对于观察的对象,没有可选择性) , 管理观察者的呢 ,通知观察者的时候,所有加入的观察者全部收到, 这种模式发现很有问题 , 没有隐私性, 大锅饭 , 所以JDK 这种模式的设计基本无人问津 , 一般都是自己实现的

所以直接转向 `事件监听者模式` 了

举报

相关推荐

0 条评论