编程设计模式之观察者模式

编程设计模式之观察者模式

为什么有观察者模式?

在软件开发中,经常会有一种场景,一个对象的状态发生变化时,需要通知其他相关的对象。如果直接在对象之间进行硬编码的依赖,会导致代码的耦合度增加,不利于后期的维护和扩展。观察者模式就是为了解决这一问题而诞生的。

观察者模式的设计思路

观察者模式也被称为发布-订阅模式,它定义了一种一对多的依赖关系,让多个观察者对象同时监听一个主题对象。当主题对象状态发生变化时,会通知所有的观察者对象,使它们能够自动更新。

观察者模式包含四个主要角色:

  1. Subject(主题):被观察的对象,它负责管理所有的观察者对象,并提供了增加、删除和通知观察者的方法。
  2. Observer(观察者):观察主题对象的变化,并在主题状态发生改变时更新自己。
  3. ConcreteSubject(具体主题):实现了主题接口,维护了一个观察者列表,并在状态发生改变时通知观察者。
  4. ConcreteObserver(具体观察者):实现了观察者接口,在接收到主题的通知时进行相应的更新操作。

Java示例代码

下面是一个简单的Java示例代码,演示了观察者模式的应用:

java 复制代码
import java.util.ArrayList;
import java.util.List;

// 主题接口
interface Subject {
    void registerObserver(Observer observer);
    void removeObserver(Observer observer);
    void notifyObservers();
}

// 观察者接口
interface Observer {
    void update(String message);
}

// 具体主题
class ConcreteSubject implements Subject {
    private List<Observer> observers = new ArrayList<>();
    private String message;

    @Override
    public void registerObserver(Observer observer) {
        observers.add(observer);
    }

    @Override
    public void removeObserver(Observer observer) {
        observers.remove(observer);
    }

    @Override
    public void notifyObservers() {
        for (Observer observer : observers) {
            observer.update(message);
        }
    }

    public void setMessage(String message) {
        this.message = message;
        notifyObservers();
    }
}

// 具体观察者
class ConcreteObserver implements Observer {
    private String name;

    public ConcreteObserver(String name) {
        this.name = name;
    }

    @Override
    public void update(String message) {
        System.out.println(name + " received message: " + message);
    }
}

// 客户端代码
public class Main {
    public static void main(String[] args) {
        // 创建具体主题
        ConcreteSubject subject = new ConcreteSubject();

        // 创建具体观察者,并注册到主题
        Observer observer1 = new ConcreteObserver("Observer1");
        Observer observer2 = new ConcreteObserver("Observer2");
        subject.registerObserver(observer1);
        subject.registerObserver(observer2);

        // 主题状态发生改变,通知观察者
        subject.setMessage("Hello, World!");
    }
}

SpringBoot工程中如何应用观察者模式

在SpringBoot工程中,观察者模式常被用于事件驱动的编程,例如Spring框架中的事件机制就是一种典型的观察者模式的应用。

首先,定义一个事件对象:

java 复制代码
public class MyEvent {
    private String message;

    public MyEvent(String message) {
        this.message = message;
    }

    public String getMessage() {
        return message;
    }
}

然后,定义观察者:

java 复制代码
@Component
public class MyObserver implements ApplicationListener<MyEvent> {
    @Override
    public void onApplicationEvent(MyEvent event) {
        System.out.println("Received event: " + event.getMessage());
    }
}

最后,在需要发布事件的地方,注入ApplicationEventPublisher并发布事件:

java 复制代码
@Service
public class MyService {
    private final ApplicationEventPublisher eventPublisher;

    @Autowired
    public MyService(ApplicationEventPublisher eventPublisher) {
        this.eventPublisher = eventPublisher;
    }

    public void doSomething() {
        // 发布事件
        eventPublisher.publishEvent(new MyEvent("Hello, World!"));
    }
}

通过这种方式,在SpringBoot工程中,我们可以方便地实现观察者模式,实现对象之间的解耦。

相关推荐
Smoothzjc18 分钟前
👉 求你了,别再裸写 fetch 做 AI 流式响应了!90% 的人都在踩这个坑
前端·人工智能·后端
superman超哥1 小时前
Rust 或模式(Or Patterns)的语法:多重匹配的优雅表达
开发语言·后端·rust·编程语言·rust或模式·or patterns·多重匹配
摸鱼的春哥2 小时前
实战:在 Docker (Windows) 中构建集成 yt-dlp 的“满血版” n8n 自动化工作流
前端·javascript·后端
IT 行者2 小时前
Spring Security 7 OAuth2 Token 格式选择浅析
java·后端·spring
幽络源小助理2 小时前
Springboot机场乘客服务系统源码 – SpringBoot+Vue项目免费下载 | 幽络源
vue.js·spring boot·后端
源代码•宸2 小时前
Golang基础语法(go语言error、go语言defer、go语言异常捕获、依赖管理、Go Modules命令)
开发语言·数据库·后端·算法·golang·defer·recover
SnrtIevg2 小时前
Vavr 用户指南
java·后端
PieroPC2 小时前
用FastAPI 一个 后端 和 两个前端 原生HTML/CSS/JS 、Vue3 写一个博客系统 例
前端·后端
Way2top2 小时前
Go语言动手写Web框架 - Gee第五天 中间件
后端·go