要么改变世界,要么适应世界

设计模式之观察者模式

2020-05-16 13:40:00
301
目录

模式介绍

定义: 在对象之间定义了一对多的依赖,这样一来,当一个对象改变状态,依赖它的对象会收到通知并自动更新。 类似于公众号订阅模式,公众号发布新通知的时候只有关注了该公众号的用户才会接收该通知。

该模式包含四个部分

  • 抽象被观察接口:将同类的所有观察者保存在一个集合中,每一个被观察者都可以被若干个观察者观察,该接口至少提供注册观察者和注销观察者方法以及通知观察者方法。
  • 抽象观察者接口: 它定义了一个更新接口,使得在得到被观察者更改通知时产生相应动作。
  • 被观察者的实现类: 将有关状态存入具体观察者对象,在具体被观察者的内部状态发生改变时,给所有注册过的观察者发送通知。
  • 观察者的实现类: 实现抽象观察者定义的更新接口,以便在得到主题更改通知时更新自身的状态。

代码实现

抽象观察者

提供抽象方法用于更新状态

interface Observer {
    void update(String msg);
}

抽象被观察者

interface Subject {
    /**
     * @param observer 需要注册的观察者
     */
    void registerObserver(Observer observer);

    /**
     * @param observer 需要注销的观察者
     */
    void removeObserver(Observer observer);

    /**
     * @param msg 需要发送的通知
     */
    void notify(String msg);
}

具体观察者

/**
 * 注意:原生JDK中 java.util.Observer 也有 Observer 接口,我们这里用的是自定义的
 */
class ObserverIplm implements Observer {
    private String name;

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

    @Override
    public void update(String msg) {
        System.out.println(name + "收到新内容,为:" + msg);
    }
}

具体被观察者

class SubjectIplm implements Subject {
    private List<Observer> observerList = new ArrayList<Observer>();

    @Override
    public void registerObserver(Observer observer) {
        this.observerList.add(observer);
    }

    @Override
    public void removeObserver(Observer observer) {
        this.observerList.remove(observer);
    }
    // 通知所有观察者
    @Override
    public void notify(String msg) {
        for (Observer item : observerList) {
            item.update(msg);
        }
    }
}

测试类

public class ObserverTest {
    public static void main(String[] args) {
        Subject mySubject = new SubjectIplm();
        Observer myObserver1 = new ObserverIplm("myObserver1");
        Observer myObserver2 = new ObserverIplm("myObserver2");
        mySubject.registerObserver(myObserver1);
        mySubject.registerObserver(myObserver2);
        mySubject.notify("震惊!Java居然是世界上最好的语言!");
        System.out.println("=====================");
        // myObserver1 颇为震惊 果断取消订阅(C生万物)
        mySubject.removeObserver(myObserver1);
        mySubject.notify("Java天下第一!");
    }
}

运行结果如下:

myObserver1收到新内容,为:震惊!Java居然是世界上最好的语言!
myObserver2收到新内容,为:震惊!Java居然是世界上最好的语言!
=====================
myObserver2收到新内容,为:Java天下第一!

总结

  • 优点:降低了耦合,使得耦合的观察者和被观察者都只依赖于抽象接口,从而各自的变换都不会影响另一方。

  • 缺点:消息通知是顺序进行,那么一个观察者卡顿,会影响整体的执行效率 。

历史评论
开始评论