前言
观察者, 即时 observer, 总结来说就是一个当一个被观察的对象的状态发生变化时, 会通知相应的观察者对象.
观察者模式定义了四种角色: 抽象主题, 具体主题, 抽象观察者, 具体观察者
1. 抽象主题 (Subject): 通常为接口或抽象类, 定义一系列操作, 如订阅, 取消订阅, 通知等方法
2. 具体主题 (Concrete Subject): 具体主题, 继承或实现抽象主题, 实现相应的逻辑, 如维护与观察者的关系, 将自身的状态变化告知观察者.
3. 抽象观察者 (Observer): 定义观察者行为
4. 具体观察者 (Concrete Observer): 实现观察者行为, 实现收到被观察者的通知后将要处理的逻辑
举个例子, Lz 比较喜欢看杂志, 所以订阅了 "意林" 杂志的公众号, 此时我就是观察者, 而 "意林" 杂志的公众号则是被观察者, 当新一期的杂志出版时, 即被观察者有状态变化, 公众号就会给我推送通知.
所以说公众号是具体主题, 而我是具体观察者, 我们之间的关系是由公众号一方来维护的.
代码演示:
- // 抽象观察者
- interface Observer{
- public void update(String message);
- }
- // 具体观察者
- class MyWeixin implements Observer{
- @Override
- public void update(String message) {
- System.out.println("我收到的通知:" + message);
- }
- }
- // 抽象主题
- interface Subject{
- // 订阅
- public void registerObserver(Observer observer);
- // 取消订阅
- public void unregisterObserver(Observer observer);
- // 通知
- public void notifyObserver(String message);
- }
- // 具体主题, 实现一系列逻辑操作, 维护与观察者的关系
- class YLi implements Subject{
- // 维护与观察者的关系
- private List<Observer> relationList = new ArrayList<>();
- @Override
- public void registerObserver(Observer observer) {
- relationList.add(observer);
- }
- @Override
- public void unregisterObserver(Observer observer) {
- relationList.remove(observer);
- }
- @Override
- public void notifyObserver(String message) {
- for (int i=0; i < relationList.size(); i++){
- Observer observer = relationList.get(i);
- observer.update(message);
- }
- }
- }
测试代码:
- public class ObserverPatternTest {
- public static void main(String[] args){
- Observer observer = new MyWeixin();
- Subject subject = new YLi();
- subject.registerObserver(observer);
- subject.notifyObserver("新的一期意林杂志出版了!");
- subject.unregisterObserver(observer);
- }
- }
控制台打印
总结: 观察者模式在有的书里又称为发布 / 订阅模式, 当需要对某个对象的状态进行检测时, 则可以使用该设计模式. 例如观察检测温度超过某阈值时, 向 App 推送短信提醒.
与 MQTT 协议的话题订阅推送其实是类似的, 基本流程都是先订阅维护一个关系, 在有状态变化时则给相应的观察者推送数据, 唯一不同的是观察与被观察的关系是由谁来维护.
来源: https://www.cnblogs.com/xiguadadage/p/10694600.html