《程序猿之设计模式实战 · 观察者模式》

📢 大家好,我是 【战神刘玉栋】,有10多年的研发经验,致力于前后端技术栈的知识沉淀和传播。 💗

🌻 CSDN入驻不久,希望大家多多支持,后续会继续提升文章质量,绝不滥竽充数,欢迎多多交流。👍

文章目录

写在前面的话

本篇文章继续介绍一下观察者模式,这个在日常工作中接触还是挺多的,但和发布订阅模式又有什么不同呢?

相关文章:
《程序猿之设计模式实战 · 策略模式》
《程序猿之设计模式实战 · 装饰者模式》
《程序猿之设计模式实战 · 池化思想》


基础介绍

观察者模式(Observer Pattern)是一种行为设计模式,它定义了一种一对多的依赖关系,使得当一个对象的状态发生变化时,所有依赖于它的对象都会得到通知并自动更新。这种模式常用于实现事件处理系统。

主要角色:

  1. 主题(Subject):被观察的对象,维护观察者的列表,并提供注册、注销观察者的方法。
  2. 观察者(Observer):对主题的变化感兴趣的对象,定义一个更新接口,以便接收主题的通知。

观察者模式的日常应用场景:

事件处理系统:如 GUI 应用中的按钮点击、文本框输入等事件的处理。

消息推送:社交媒体应用中,当用户发布新内容时,所有关注该用户的用户都会收到通知。

股票市场:当股票价格变化时,所有订阅该股票的投资者都会收到更新。

天气监测:天气预报应用中,用户可以订阅天气变化的通知。

日志系统:在日志框架中,多个观察者可以监听日志事件并执行相应的处理(如写入文件、发送邮件等)。


代码实现

Spring的事件用法就是典型的观察者模式。

实现步骤:

Step1、创建自定义事件

java 复制代码
public class CustomEvent extends ApplicationEvent {
    private String message;

    public CustomEvent(Object source, String message) {
        super(source);
        this.message = message;
    }

    public String getMessage() {
        return message;
    }
}

Step2、创建事件监听器

java 复制代码
@Component
public class CustomEventListener {

    @EventListener
    public void handleCustomEvent(CustomEvent event) {
        System.out.println("Received custom event - Message: " + event.getMessage());
    }
}

Step3、创建事件发布者

java 复制代码
@Component
public class EventPublisher {
    private final ApplicationEventPublisher publisher;

    public EventPublisher(ApplicationEventPublisher publisher) {
        this.publisher = publisher;
    }

    public void publish(String message) {
        CustomEvent event = new CustomEvent(this, message);
        publisher.publishEvent(event);
    }
}

Step4、合适的位置触发一下事件,例如下方的服务初始化。

java 复制代码
@Component
public class AppRunner implements CommandLineRunner {

    private final EventPublisher eventPublisher;

    @Autowired
    public AppRunner(EventPublisher eventPublisher) {
        this.eventPublisher = eventPublisher;
    }

    @Override
    public void run(String... args) throws Exception {
        eventPublisher.publish("Hello, Observer Pattern!");
    }
}

观察者&发布订阅

观察者模式和发布-订阅模式(Publish-Subscribe Pattern)有相似之处,但它们之间也存在一些关键的区别:

1、耦合度:

观察者模式:主题和观察者之间是直接的依赖关系。观察者需要知道主题的存在,并注册到主题中。

发布-订阅模式:发布者和订阅者之间是解耦的。发布者不需要知道任何订阅者的存在,反之亦然。它们通过一个中介(如消息代理)进行通信。

2、通信方式:

观察者模式:通常是同步的,观察者在主题状态变化时立即收到通知。

发布-订阅模式:可以是同步或异步的,发布者发布消息后,订阅者可以在稍后时间接收消息。

3、使用场景:

观察者模式:适用于一对多的关系,通常在同一个应用程序中使用。

发布-订阅模式:适用于分布式系统或微服务架构,允许不同的应用程序或服务之间进行通信。

总结:

观察者模式和发布-订阅模式都用于实现事件驱动的架构,但它们在耦合度、通信方式和使用场景上有所不同。选择哪种模式取决于具体的需求和应用场景。


补充说明

按前面内容所介绍的,好像发布订阅模式的使用场景更广,比如 RedisTemplate.convertAndSend 方法在 Spring 中用于将消息发送到 Redis 的某个频道。这种机制可以被视为一种发布-订阅模式的实现,而不是严格的观察者模式。又比如Kafka 中的生产者和消费者的交互属于典型的发布-订阅模式。

这里再分析比对一下两者。

发布-订阅模式

使用场景:适用于需要在不同组件之间进行松耦合通信的场景。比如,使用 Redis、Kafka 等消息中间件时,发布者和订阅者之间没有直接的依赖关系。

优点:可以轻松扩展,添加新的订阅者不需要修改发布者的代码,适合分布式系统。

观察者模式

使用场景:通常用于对象之间的直接关系,适合在同一应用程序内部进行事件通知。Spring 的事件机制就是一个典型的例子。

优点:实现简单,适合在内存中处理事件,适合小范围的事件传播。

总结一下:

发布-订阅模式:适合跨服务或组件的通信,使用消息中间件。

观察者模式:适合在同一应用程序内部的事件处理,使用 Spring 的事件机制。

这两种模式各有其适用场景,选择时可以根据具体需求来决定。


总结陈词

还是那句话,不用过多的纠结在用的是哪个设计模式,实现的是什么标准。

遇到实际问题能使用合适的方式解决,同时代码经得起推敲和扩展,才是最主要的。

还是那句话,你可以不用,但不能不会。

💗 后续会逐步分享企业实际开发中的实战经验,有需要交流的可以联系博主。

相关推荐
“AI国潮设计-小江”1 小时前
【AIGC实战】Python+SDXL批量生成“潮汕英歌舞不倒翁”IP | 角色一致性与多场景融合方案,附完整代码
开发语言·人工智能·python·prompt·aigc
Linux_cy1 小时前
服务器管理工具哪个好用?我用了七八个
运维·服务器·javascript·python·ssh·面板·gmssh
MoRanzhi12032 小时前
第6篇(下)· 使用 PyQt5 实现 2048 高性能计算版:统一运行控制与跨模式安全交接
python·pyqt·进程管理·状态机·软件架构·并发控制·数据一致性
code tsunami2 小时前
【无标题】
开发语言·python
CodeGL2 小时前
10、Python基础之进程和线程
开发语言·python
TechWayfarer3 小时前
PHP漏洞被利用,怎么揪出攻击IP?
开发语言·python·tcp/ip·网络安全·php
2601_967980114 小时前
Python列表操作方法详解
python·数据类型·修改·列表操作·功能汇总
Patrick在香港5 小时前
台风在变少,来香港的没有
python·数据分析·香港·开放数据·热带气旋
qq_406981035 小时前
大白话rust系列09 函数调用两次有什么错?
开发语言·python·rust
benchmark_cc5 小时前
QuantDash 安装成功后,如何验证 Python 环境可以正常导入 SDK?
开发语言·python·数据分析·pandas·量化交易·股票数据·quantdash