• 设计模式-观察者模式


    概述

    • 观察者设计模式(Observer Design Pattern)是一种行为型设计模式,它主要用于解决对象间的一对多依赖问题,当一个对象的状态发生改变时,所有依赖于它的对象都能得到通知并自动更新状态,无需显式调用。
    • 该模式的核心思想是解耦,通过引入中间层,确保主题(Subject)与观察者(Observer)之间的松耦合联系。

    核心思想

    • 抽象主题(Subject):持有多个观察者对象的引用,抽象主题提供了一个接口可以增加和删除观察者对象;有一个观察者数组,并实现增、删及通知操作
    • 具体主题(Concrete Subject):将有关状态存入具体观察者对象,在具体主题内部状态改变时,给所有登记过的观察者发出通知
    • 抽象观察者(Observer):定义一个接口,包含更新方法,供具体的观察者实现
    • 具体观察者(Concrete Observer):实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题的状态保持一致

    在这里插入图片描述

    场景使用

    • GUI应用程序
      • 在图形用户界面(GUI)开发中,观察者模式用于建立组件之间的联动关系。例如,当用户在界面上的一个控件(如文本框)中输入数据时,其它相关控件(如统计面板或图表)能够实时更新显示。
    • 订阅/发布系统
      • 在消息传递或事件驱动架构中,观察者模式常用于实现发布-订阅机制。发布者(Subject)向订阅者(Observers)发送通知,如在消息队列、事件总线或RSS新闻订阅系统中,每当有新消息或文章发布时,所有已订阅的用户或组件都会接收到更新通知。
    • 数据绑定
      • 在前端框架(如Angular、Vue、React)中,数据双向绑定就是观察者模式的一种体现。视图层作为观察者监听模型层数据的变化,一旦模型数据更改,视图层能自动更新。
    • 数据库同步
      • 数据库触发器或者缓存系统,当数据库表中的记录发生变化时,可以触发一系列的后续操作,如更新关联表、清除缓存或通知其他服务进行数据同步。

    总之,观察者模式适用于任何需要在对象状态改变时自动通知多个对象,并且这些对象需要及时作出相应更新的情况。这样可以保持对象间的松耦合,提高程序的可维护性和可扩展性。

    优缺点

    优点

    • 降低了目标与观察者之间的耦合关系,目标与观察者之间建立了一套触发机制
    • 观察者和被观察者是抽象耦合的

    缺点

    • 观察者和观察目标之间有循环依赖的话,会触发它们之间进行循环调用,可能导致系统崩溃
    • 一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间

    示例

    Subject 抽象主题

    
    import java.util.ArrayList;
    import java.util.List;
    
    public class Subject {
    
        private List<Observer> observerList = new ArrayList<>();
    
        /**
         * 新增观察者
         *
         * @param observer
         */
        public void addObserver(Observer observer) {
            this.observerList.add(observer);
        }
    
        /**
         * 删除观察者
         *
         * @param observer
         */
        public void deleteObserver(Observer observer) {
            this.observerList.remove(observer);
        }
    
        public void notifyAllObserver() {
            for (Observer observer : this.observerList) {
                observer.update();
            }
        }
    }
    
    • 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

    BossConcreteSubject 具体主题

    public class BossConcreteSubject extends Subject {
    
        public void doSomething() {
            System.out.println("老板完成自己的工作");
            //业务操作
            System.out.println("视察公司工作情况");
            super.notifyAllObserver();
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    Observer 抽象观察者

    public interface Observer {
    
        /**
         * 观察到消息后进行的操作,就是响应
         */
        void update();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    具体观察者

    public class XSConcreteObserver implements Observer {
        @Override
        public void update() {
            System.out.println("小帅发现领导到来,暂停在线摸鱼,回归工作");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    public class XMConcreteObserver implements Observer {
        @Override
        public void update() {
            System.out.println("小美发现领导到来,暂停在线摸鱼,回归工作");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    测试

    public class Main {
        public static void main(String[] args) {
            //创建一个主题,老板
            BossConcreteSubject subject = new BossConcreteSubject();
    
            //创建观察者,就是摸鱼的同事
            Observer xmObserver = new XMConcreteObserver();
    
            //创建观察者,就是摸鱼的同事
            Observer xsObserver = new XSConcreteObserver();
    
            //建立对应的关系,老板这个主题被同事进行观察
            subject.addObserver(xsObserver);
            subject.addObserver(xmObserver);
    
            //主题开始活动,里面会通知观察者(相当于发布消息)
            subject.doSomething();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    在这里插入图片描述

  • 相关阅读:
    Vue3 除了keep-alive,还有哪些页面缓存的实现方案
    后台管理----搜索,重置功能
    ARP协议;DHCP协议;ICMP协议
    指纹浏览器是什么?可以用来解决流量套利的什么问题?
    Spring Boot集成Quartz快速入门Demo
    2022 年杭电多校第九场补题记录
    【x265 源码分析系列】:概述
    山石网科国产化防火墙,打造全方位边界安全解决方案
    Uniapp 动态修改状态栏、导航栏背景色、字体颜色插件 Ba-AppBar
    linux软链接的创建、删除和更新
  • 原文地址:https://blog.csdn.net/laow1314/article/details/138049829