首页 > 其他分享 >掌握设计模式--观察者模式

掌握设计模式--观察者模式

时间:2025-01-18 17:57:18浏览次数:3  
标签:temperature Observer -- 通知 主题 观察者 更新 设计模式

观察者模式(Observer Pattern)

观察者模式(Observer Pattern)是一种行为设计模式,它定义了对象间的一对多依赖关系,使得当一个对象状态发生改变时,所有依赖于它的对象都会自动收到通知并更新。

主要组成部分

主题(Subject):主题是被观察的对象,它维护一个观察者列表。当它的状态发生改变时,会通知所有的观察者。主题提供方法来注册、注销观察者。

观察者(Observer):观察者是依赖于主题的对象,它会在主题状态发生变化时收到通知,进而更新自身的状态。观察者有一个更新方法,当主题状态变化时,主题会调用此方法来通知观察者。

工作流程

  1. 注册观察者:观察者通过主题提供的注册方法将自己注册到主题上。

  2. 状态变化:主题的状态发生变化时,它会遍历其所有注册的观察者。

  3. 通知观察者:主题调用每个观察者的更新方法,通知它们进行状态更新。

  4. 更新观察者:观察者根据通知更新自己的状态,通常会重新渲染界面或进行其他的状态更新。

案例实现

假设有一个温度监控系统:

  • 主题:温度传感器,当温度发生变化时,它会通知所有依赖于它的观察者。

  • 观察者:可以是不同的显示设备或报警系统,温度变化时,它们会根据新温度执行相应操作。

案例类图

image

观察者接口

用于观察温度变化的接口,订阅的主题发生变化时,通过观察者接口的update方法来通知订阅了的所有观察者。

interface Observer {
    void update(int temperature);
}

观察者实现类

// 观察者实现类1
class DisplayDevice implements Observer {
    @Override
    public void update(int temperature) {
        System.out.println("显示装置:温度更新到" + temperature);
    }
}

// 观察者实现类2
class AlarmSystem implements Observer {
    @Override
    public void update(int temperature) {
        if (temperature > 42) {
            System.out.println("警报:温度超过阈值!");
        }
    }
}

主题类(被观察者)

class TemperatureSensor {
    // 观察者列表
    private List<Observer> observers = new ArrayList<>();
    private int temperature;

    // 注册观察者
    public void addObserver(Observer observer) {
        observers.add(observer);
    }

    // 移除观察者
    public void removeObserver(Observer observer) {
        observers.remove(observer);
    }

    // 设置温度并通知观察者
    public void setTemperature(int temperature) {
        this.temperature = temperature;
        notifyObservers();
    }

    // 通知所有观察者
    private void notifyObservers() {
        for (Observer observer : observers) {
            observer.update(temperature);
        }
    }
}

测试客户端

public class ObserverPatternDemo {
    public static void main(String[] args) {
        // 创建主题和观察者
        TemperatureSensor sensor = new TemperatureSensor();
        Observer display = new DisplayDevice();
        Observer alarm = new AlarmSystem();

        // 注册观察者:如果没注册,那就不会通知
        sensor.addObserver(display);
        sensor.addObserver(alarm);

        // 改变主题的状态
        sensor.setTemperature(45);
        sensor.setTemperature(28);
    }
}

测试输出结果

显示装置:温度更新到45

警报:温度超过阈值!

显示装置:温度更新到28

优缺点和使用场景

优点

  1. 松耦合:观察者与主题之间是松耦合的,主题不需要知道具体的观察者,观察者也不需要了解主题的内部实现。

  2. 动态添加或删除观察者:可以在运行时动态地添加或删除观察者。

缺点

  1. 多次更新:如果有大量观察者,状态变化可能导致多次调用更新方法,性能可能受到影响。

  2. 循环依赖:观察者之间如果互相通知更新,可能引起循环依赖或无限循环。

观察者模式是处理事件驱动系统或需要多个对象同步更新状态的常用模式,尤其在分布式系统、GUI框架中应用广泛。

适用场景

  • 事件驱动的系统:例如GUI框架(按钮点击、界面更新等)、消息通知系统等。

  • 发布-订阅系统:如消息队列系统、新闻订阅、社交媒体更新等。

  • 数据同步:多个模块需要同步更新某些共享数据时,如温度监控、股票价格变化等。

观察者模式的应用

Spring的事件机制ApplicationEvent是事件对象,ApplicationListener是事件监听器,当ApplicationEvent发布时,所有注册了该事件类型的ApplicationListener会被通知并处理该事件。ApplicationEventPublisher接口(通常是ApplicationContext的实现类)作为被观察者,ApplicationListener作为观察者。事件的发布和监听实现了松耦合的通知机制。

Java Web中的监听器,它通过监听和响应Web应用的生命周期事件、HTTP会话事件、请求事件以及属性变化事件。常见的监听器接口包括ServletContextListenerHttpSessionListenerServletRequestListener等,实现相应的监听接口,即可完成相应事件的监听。监听器机制的使用可以帮助开发者在特定事件发生时执行一些处理逻辑,保证代码的解耦和灵活性。

总结

观察者模式是一种行为设计模式,其核心在于通过定义一对多的依赖关系,使得当被观察者的状态发生变化时,所有依赖的观察者自动收到通知并更新,从而实现对象之间的松耦合和动态响应,同时便于观察者的扩展。

文章转载自:渊渟岳

原文链接:掌握设计模式--观察者模式 - 渊渟岳 - 博客园

体验地址:引迈 - JNPF快速开发平台_低代码开发平台_零代码开发平台_流程设计器_表单引擎_工作流引擎_软件架构

标签:temperature,Observer,--,通知,主题,观察者,更新,设计模式
From: https://blog.csdn.net/kfashfasf/article/details/145222326

相关文章

  • 深入解析d3dx9_39.dll丢失及有效修复方法?为何会出现d3dx9_31.dll丢失?该如何应对?
    在计算机使用过程中,不少用户都遭遇过d3dx9_39.dll丢失的困扰。d3dx9_39.dll丢失究竟是怎么一回事呢?d3dx9_39.dll是DirectX9.0cRedistributable的重要组成部分。许多游戏和图形相关软件在运行时依赖它来实现各种图形渲染、动画展示等功能。当d3dx9_39.dll丢失时,这些依赖它的程......
  • 速戳!低代码技术赋能新型工业化背后,竟藏着这些不为人知的秘密!
    目录一、引言二、新型工业化的时代背景2.1工业发展的新阶段2.2新型工业化的目标与需求三、低代码技术的独特魅力3.1低代码技术的基本概念3.2与传统开发的对比优势四、低代码赋能新型工业化的秘密4.1降低技术门槛,全民参与创新4.2加速应用开发,快速响应市场4.3......
  • Permutation Swaps
    PermutationSwaps传送门题目理解第一个操作:把第i个数移到位置p[i](1<=i<=n)​发现:这个操作其实就是循环移位,有Teleporter的经验在前,此操作可用倍增\(\log_{2}^{n}\)实现,同时可 以推出此操作可以叠加,所以用一个sum记录操作次数,查询时一次解决​第二个操作:交换两个位置,此操作......
  • 列空间和零空间 Column Space & Nullspace
    列空间和零空间ColumnSpace&Nullspace​ 在上一节的线性空间中,提到\(\symbf{R}^n\)子空间有过零点的平面和直线两种(3维及以上),可以分别记为\(\symbf{P}\)和\(\symbf{L}\)。​ 那么便有如下问题:\(\symbf{P}\cup\symbf{L}\)一定是向量空间吗?​ 答案是否定的,显然该空间对加......
  • EditPlus 3.x、4.x、5.x 激活码
    EditPlus是一款适用于Windows的文本编辑器,具有内置的FTP、FTPS和sftp功能。虽然它可以作为一个很好的记事本替代品,但它还为网页作者和程序员提供了许多强大的功能。Editplus5.x注册码注册名:damie注册码:ANE0N-LZ7HA-9Y4IT-DBKA3-K7NIQ注册名:hello注册码:UAYJE-GTIV8-GQD......
  • 「NOIP2024」 树上查询
    update2024/12/28题目描述给定一棵树,每次询问区间\([l,r]\)的\[\max_{l\lel'\ler'\ler\landr'-l'+1\gek}\text{dep}_{\text{LCA*}(l',r')}\]引理证明先来证两个区间\(\text{LCA}\)的引理:对于\(\text{LCA}\{l,l+1,\dots......
  • 【设计模式与体系结构】结构型模式-装饰模式
    简介装饰模式(DecoratorPattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。装饰模式是用组合的方式将装饰对象和被装饰对象组合在一起,当调用装饰后的对象的方法时,实际是......
  • [ARC 188A] ABC Symmetry
    solutionbyXiangXunYi思路推导step1首先题目中操作二同时删掉A,B,C的条件相当于同时将三者数量减一,操作一删掉两个相同字符等同于将某一字符的数量减二,那么我们可以发现只使用操作一不会改变奇偶,操作二则是同时反转奇偶,所以一个字符串是个好字符串的必要条件是其中三个字母......
  • 1月省选联考做题记录
    CF1434EAConvexGametag:DP,交换值域,博弈论,凸性。首先,由于每组数是分开考虑的,题目可以看作一个组合游戏,也就是说我们可以分开考虑每个游戏的SG值。对于每一组游戏,套路地考虑构建一个有向图模型。注意到每一步的选择与差是有关的,考虑记录\(f_{i,j}\)为,现在\(b\)数组的最后......
  • C++基础学习03
    C++基础学习032025-01-1715:59:09星期五关于数组数组有几个特点固定大小相同的数据类型连续存储这点就是说数组在内存中是连续存储的下标访问这点就是我们可以通过[num]的方式来对数组进行访问一般来说,我们使用dataTypearrayName[arraySize]的方式来创建......