观察者模式
一 . 初步认识观察者模式 ( 出版者+订阅着=观察者模式 )
留意我们生活中报纸和杂志的订阅是怎么个流程:
-
报社的业务就是出版报纸。
-
向某家报社订阅报纸,只要他们有新报纸出版,就会给你送来。只要你是他们的订户,你就会一直收到新报纸。
-
当你不想再看报纸的时候,取消订阅,他们就不会再送新报纸来。
- 只要报社还在运营,就会一直有人( 或单位 )订阅报纸或取消订阅报纸。
如果了解报纸的订阅过程是怎么一回事,其实也就知道了观察者模式是怎么回事了,只是名称不太一样:出版社改称为 “主题” ( Subject ),订阅者改为 “观察者”( Observer )。
二 . 观察者模式的定义
观察者模式定义了对象之间一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。
三 . 定义观察者模式的类图
在观察者模式中有如下角色:
-
Subject :抽象主题(抽象被观察者)。抽象主题角色把所有观察者对象保存在一个集合里,每个主题都可以有任意数量的观察者。抽象主题提供一个接口。可以增加和删除观察者对象。
-
ConcreteSubject :具体主题(具体被观察者)。该角色将有关状态存入具体观察者对象,在具体主题的内部状态发生改变时,给所有注册过的观察者发送通知。
-
Observer :抽象观察者。是观察者的抽象类。它定义了一个更新接口,使得在得到主题更改通知时更新自己。
-
ConcreteObserver :具体观察者,实现抽象观察者定义的更新接口。以便在得到主题更改通知时更新自身的状态。
四 . 观察者模式的简单实现
在这里用文章开头的订阅报纸的例子来详细说明观察者模式的使用,代码实现及分析如下:
(1)抽象被观察者
抽象被观察者是一个接口,里面定义了 registerObserver ( ) , removeObserver ( ) , notifyObserver ( ) 三个方法,代码如下所示:
(2)具体被观察者
报纸出版社时具体主题,也就是具体的被观察者,里面存储了订阅该出版社报纸的用户,并实现了抽象主题中的方法,代码如下所示:
(3)抽象观察者
抽象观察者是一个接口,里面只定义了一个更新的方法,代码如下所示:
(4)具体观察者
订阅者用户是订阅者,里面实现了更新的方法,代码如下所示:
(5)客户端调用
代码如下所示:
五 . 观察者模式使用场景
观察者模式使用场景:
-
关联行为场景。需要注意的是,关联行为是可以拆分的,而不是 “组合” 关系。
-
事件多级出发场景。
-
跨系统的消息交换场景,如消息队列、事件总线的处理机制。
六 . 观察者模式的优缺点
(1)观察者模式优点:
-
观察者和被观察者之间是抽象松耦合,容易扩展。
-
方便建立一套触发机制。
(2)观察者模式缺点:
在应用观察者模式时需要考虑一下开发效率和运行效率的问题。程序中包括一个被观察者、多个观察者,开发、调试等内容会比较复杂,而且在 Java 中消息的通知一般时顺序执行的,那么一个观察者卡顿,会影响整体的执行效率,在这种情况下,一般会采用异步方法。