观察者模式

观察者模式是软件设计模式的一种。在此种模式中,一个目标对象管理所有相依于它的观察者对象,并且在它本身的状态改变时主动发出通知。这通常透过呼叫各观察者所提供的方法来实现。此种模式通常被用来实时事件处理系统。

定义

关于定义,最准确的莫过于Head First设计模式中写到的。

观察者模式定义了一个一对多的依赖关系,让一个或多个观察者对象监听一个主题对象。这样一来,当被观察者状态发生改变时,需要通知相应的观察者,使这些观察者对象能够自动更新。

关键要素

观察者模式_第1张图片
obeserver

(抽象)主题 Subject

主题,也就是被观察者(Observable),是观察者观察的对象,一个主题必须具备下面三个特征。

  • 持有监听的观察者的引用
  • 支持增加和删除观察者
  • 主题状态改变,通知观察者

具体主题 ConcreteSubject

该角色将有关状态存入具体观察者对象,在具体主题的内部状态发生改变时,给所有注册过的观察者发出通知,具体主题角色又叫做具体观察者(Concrete Observable)

(抽象)观察者 Observer

当主题发生变化,收到通知,进行具体的处理。

具体观察者 ConcreteObserver

该角色实现抽象观察者角色所定义的更新接口,以备在主题的状态发生变化时更新自身的状态。

为什么要用这种模式

这里举一个例子来说明,牛奶送奶站就是主题,订奶客户为监听者,客户从送奶站订阅牛奶后,会每天收到牛奶。如果客户不想订阅了,可以取消,以后就不会收到牛奶。

松耦合

  • 观察者增加或删除无需修改主题的代码,只需调用主题对应的增加或者删除的方法即可。
  • 主题只负责通知观察者,但无需了解观察者如何处理通知。举个例子,送奶站只负责送递牛奶,不关心客户是喝掉还是洗脸。
  • 观察者只需等待主题通知,无需观察主题相关的细节。还是那个例子,客户只需关心送奶站送到牛奶,不关心牛奶由哪个快递人员,使用何种交通工具送达。

通知不错过

由于被动接受,正常情况下不会错过主题的改变通知。而主动获取的话,由于时机选取问题,可能导致错过某些状态。

Java实现

public class ObserverMain {

    //好处:松耦合(被观察者可以增加删除观察者;被观察者只负责通知观察者;观察者只需等待通知;)
    //     通知不错过(被动接受,不易错过通知)

    public static void main(String[] args) {

        MilkProvider provider = new MilkProvider();

        Consumer consumer1 = new Consumer("道格拉斯");
        Consumer consumer2 = new Consumer("图灵");
        Consumer consumer3 = new Consumer("牛顿");

        provider.addObserver(consumer1);
        provider.addObserver(consumer2);
        provider.addObserver(consumer3);
        provider.deleteObserver(consumer3);

        provider.milkProduced("草莓味的牛奶");
    }

    // 静态成员属于类,不需要生成对象就存在了.
    // 而非静态需要生成对象才产生,所以静态成员不能直接访问.所以声明为静态类

    // 被观察者 牛奶站
    static class MilkProvider extends Observable {

        // 牛奶做好啦
        public void milkProduced(String milkType) {
            // 标识状态或内容发生改变
            setChanged();
            // 通知所有订奶的客户(观察者)
            notifyObservers(milkType);
        }
    }

    //观察者 订奶的客户
    static class Consumer implements Observer {

        private String name;

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

        @Override
        public void update(Observable observable, Object o) {
            System.out.println("Hi, " + name + " 牛奶做好啦!" + " observable=" + observable + " o=" + o);
        }

        @Override
        public String toString() {
            return "toString " + name;
        }
    }

}

参考资料:

这就是观察者模式
观察者模式- 23种设计模式
观察者模式— Graphic Design Patterns

你可能感兴趣的:(观察者模式)