• Java观察者模式之总有你想不到的知识


    观察者模式

    概念

    观察者模式(Observer Pattern)也称发布订阅模式,它的目的是定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并被自动更新

    在这里插入图片描述

    观察者模式的类图如下图所:

    在这里插入图片描述

    观察者模式具有以下4个角色:

    角色说明
    抽象主题(Subject)角色该角色又称为“被观察者”,可以增加和删除观察者对象。
    抽象观察者(Observer)角色该角色为所有的具体观察者定义一个接口,在得到主题的通知时更新自己。
    具体主题(Concrete Subject)角色该角色又称为“具体被观察者”,它将有关状态存入具体观察者对象,在具体主题的内部状态改变时,给所有登记过的观察者发出通知。
    具体观察者(Concrete Observer)角色该角色实现抽象观察者所要求的更新接口,以便使自身的状态与主题的状态相协调。

    代码案例:

    定义抽象主题(Subject)角色类

    package com.shixun.design.observer;
    
    /**
     * 抽象主题:被观察者
     */
    interface Subject {
        // 登记一个新的观察者
        public void attach(Observer obs);
    
        // 删除一个登记过的观察者
        public void detach(Observer obs);
    
        // 通知所有登记过的观察者对象
        public void notifyObserver();
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    定义抽象观察者(Observer)角色类

    package com.shixun.design.observer;
    
    /**
     * 抽象观察者:为所有的具体观察者定义一个接口
     */
    interface Observer {
        // 更新方法
        public void update();
    }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    定义具体主题(Concrete Subject)角色类

    package com.shixun.design.observer;
    
    import java.util.Enumeration;
    import java.util.Vector;
    
    /**
     * 具体主题:具体被观察者
     */
    class ConcreteSubject implements Subject {
        private Vector<Observer> obsVector = new Vector<Observer>();
    
        // 登记一个新的观察者
        public void attach(Observer obs) {
            obsVector.add(obs);
        }
    
        // 删除一个登记过的观察者
        public void detach(Observer obs) {
            obsVector.remove(obs);
        }
    
        // 通知所有登记过的观察者对象
        public void notifyObserver() {
            for (Observer e : obsVector) {
                e.update();
            }
        }
    
        // 返回观察者集合的Enumeration对象
        public Enumeration<Observer> observers() {
            return obsVector.elements();
        }
    
        // 业务方法,改变状态
        public void change() {
            this.notifyObserver();
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    定义具体观察者(Concrete Observer)角色类

    package com.shixun.design.observer;
    
    /**
     * 具体观察者:实现抽象观察者所要求的更新接口
     */
    class ConcreteObserver implements Observer {
        // 实现更新方法
        public void update() {
            System.out.println(this+"收到通知,并进行处理!");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    定义测试类:

    package com.shixun.design.observer;
    
    import com.shixun.design.strategy.ConcreteStrategy;
    import com.shixun.design.strategy.Context;
    
    public class Test {
        public static void main(String[] args) {
            ConcreteSubject subject = new ConcreteSubject();
    
            ConcreteObserver observer = new ConcreteObserver();
            ConcreteObserver observer1 = new ConcreteObserver();
            ConcreteObserver observer2 = new ConcreteObserver();
            subject.attach(observer);
            subject.attach(observer1);
            subject.attach(observer2);
    
            subject.change();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    运行结果如下:
    在这里插入图片描述

    优缺点

    优点

    观察者模式具有以下几个优点:

    • 观察者和被观察者之间是抽象耦合。被观察者角色所知道的只是一个具体观察者集合,每一个具体观察者都符合一个抽象观察者的接口。被观察者并不认识任何一个具体的观察者,它只知道它们都有一个共同的接口。由于被观察者和观察者没有紧密的耦合在一起,因此它们可以属于不同的抽象化层次,且都非常容易扩展。

    • 支持广播通信。被观察者会向所有登记过的观察者发出通知,这就是一个触发机制,形成一个触发链

    缺点

    观察模式的缺点如下:

    • 如果一个主题有多个直接或间接的观察者,则通知所有的观察者会花费很多时间,且开发和调试都比较复杂
    • 如果在主题之间有循环依赖,被观察者会触发它们之间进行循环调用,导致系统崩溃。在使用观察者模式时要特别注意这一点。
    • 如果对观察者的通知是通过另外的线程进行异步投递,系统必须保证投递的顺序执行
    • 虽然观察者模式可以随时使观察者知道所观察的对象发生了变化,但是观察者模式没有提供相应的机制使观察者知道所观察的对象是如何发生变化

    应用场景

    观察者模式的应用场景如下:

    • 关联行为场景
    • 事件多级触发场景
    • 跨系统的消息交换场景,如消息队列的处理机制
  • 相关阅读:
    JAVA 集合框架(二) List集合详解和常用方法
    《mSystems》比较宏基因组学探究海洋和陆地生态系统中磷酸盐分解代谢途径
    easyExcel获取动态表头和筛选数据导出的问题
    C++类继承
    多商户商城系统功能拆解20讲-平台端分销概况
    IS ATTENTION BETTER THAN MATRIX DECOMPOSITION
    JAVA核酸预约检测管理系统毕业设计 开题报告
    RabbitMQ笔记
    nodejs+vue流浪猫狗救助领养elementui
    pytest-html中文乱码
  • 原文地址:https://blog.csdn.net/weixin_45525272/article/details/126303233