23种设计模式 -【观察者】

观察者模式

概述

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

本质理解

观察者模式的本质就是:被观察者调用观察者的虚函数,由观察者自己决定如何响应通知,从而实现解耦的一对多通知机制。

主题(被观察者 Subject)

  • 保存所有观察者(Observer)的指针列表
  • 当自身状态变化时,调用每个观察者的虚函数 update()

观察者(Observer 接口)

  • 定义一个纯虚函数 update()
  • 所有具体观察者必须实现 update(),处理收到的通知

核心流程

复制代码
主题状态改变 → 调用 notify() → 遍历所有观察者 → 调用每个观察者的 update()
  • notify() 就是桥梁,负责把主题的变化推送给观察者
  • update() 是观察者接收通知的入口,具体行为由子类实现

代码实现(C++)

cpp 复制代码
#include <iostream>
#include <vector>
using namespace std;

// -------- 观察者接口 --------
// 定义一个抽象观察者接口,所有具体观察者都必须实现 update 方法
class Observer {
public:
    virtual void update(int value) = 0;  // 状态更新接口,由主题调用
    virtual ~Observer() = default;       // 虚析构函数,保证子类对象正确销毁
};

// -------- 主题(Subject) --------
class Subject {
    vector<Observer*> observers;  // 保存所有注册的观察者指针
    int state;                     // 主题的内部状态

public:
    // 注册观察者
    void attach(Observer* obs) {
        observers.push_back(obs);
    }

    // 移除观察者
    void detach(Observer* obs) {
        // 使用 STL remove-erase idiom 删除指定观察者
        observers.erase(
            remove(observers.begin(), observers.end(), obs),
            observers.end()
        );
    }

    // 修改主题状态
    void setState(int val) {
        state = val;    // 更新内部状态
        notify();       // 状态变化后通知所有观察者
    }

    // 通知所有观察者
    void notify() {
        for (auto obs : observers)
            obs->update(state);  // 调用观察者的 update 方法
    }
};

// -------- 具体观察者 --------

// 具体观察者 A
class ObserverA : public Observer {
public:
    void update(int value) override {
        cout << "ObserverA 收到更新,值 = " << value << endl;
    }
};

// 具体观察者 B
class ObserverB : public Observer {
public:
    void update(int value) override {
        cout << "ObserverB 收到更新,值 = " << value << endl;
    }
};

// -------- 主程序 --------
int main() {
    Subject subject;   // 创建主题对象

    ObserverA a;       // 创建具体观察者 A
    ObserverB b;       // 创建具体观察者 B

    subject.attach(&a);   // 注册观察者 A
    subject.attach(&b);   // 注册观察者 B

    // 修改状态,自动通知所有注册观察者
    subject.setState(10); // 输出 A 和 B 的 update
    subject.setState(20); // 再次输出 A 和 B 的 update

    return 0;
}

运行结果

复制代码
ObserverA 收到更新,值 = 10
ObserverB 收到更新,值 = 10
ObserverA 收到更新,值 = 20
ObserverB 收到更新,值 = 20

核心角色

角色 说明
Subject(主题) 维护观察者列表,提供注册/注销接口,状态变化时通知观察者
Observer(观察者) 抽象接口,定义 update() 方法供主题调用
ConcreteObserver(具体观察者) 实现 update(),定义收到通知后的具体行为

设计原则

  • 封装变化:将可能变化的部分(观察者列表)独立出来
  • 面向接口编程:主题和观察者都通过抽象接口交互
  • 松耦合:主题不需要知道观察者的具体类型

应用场景

  • GUI 事件系统(如按钮点击通知多个监听器)
  • MVC / MVVM 架构中的数据绑定
  • 消息推送系统
  • 股票行情监听
  • 社交媒体关注通知

模式对比

对比项 观察者模式 发布-订阅模式
通信方式 主题直接通知观察者 通过消息代理中间件
耦合度 更紧密 更松散
适用场景 进程内 跨进程/跨服务
相关推荐
geovindu10 小时前
go: Observer Pattern
开发语言·观察者模式·设计模式·golang
z小天才b1 天前
Java 设计模式完全指南:从入门到精通
java·开发语言·设计模式
kyriewen111 天前
Next.js:让你的React应用从“裸奔”到“穿衣服”
开发语言·前端·javascript·react.js·设计模式·ecmascript
A-Jie-Y1 天前
JAVA设计模式-工厂方法模式
java·设计模式
A-Jie-Y1 天前
JAVA设计模式-单例模式
java·设计模式
geovindu1 天前
go: Iterator Pattern
开发语言·设计模式·golang·迭代器模式
Ting.~1 天前
软件设计师备考笔记【day2】-UML 图解 | 面向对象 | 设计模式
笔记·设计模式·uml
qcx231 天前
深入解析,什么是Agent,Agent的 架构与设计模式
设计模式·架构
geovindu2 天前
go: Chain of Responsibility Pattern
开发语言·设计模式·golang·责任链模式
AndreasEmil2 天前
基于多设计模式的抽奖系统 - 测试报告
java·selenium·设计模式·postman