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 架构中的数据绑定
  • 消息推送系统
  • 股票行情监听
  • 社交媒体关注通知

模式对比

对比项 观察者模式 发布-订阅模式
通信方式 主题直接通知观察者 通过消息代理中间件
耦合度 更紧密 更松散
适用场景 进程内 跨进程/跨服务
相关推荐
妙蛙种子3114 小时前
【Java设计模式 | 创建者模式】 抽象工厂模式
java·开发语言·后端·设计模式·抽象工厂模式
怨言.5 小时前
设计模式之模板方法模式
设计模式·模板方法模式
无籽西瓜a5 小时前
【西瓜带你学设计模式 | 第十四期 - 享元模式】享元模式 —— 内外状态分离与对象共享实现、优缺点与适用场景
java·设计模式·软件工程·享元模式
七夜zippoe6 小时前
设计模式在Spring等框架中的应用:模板方法、工厂、适配器等
java·spring·设计模式·模板·适配器·工厂
panzer_maus7 小时前
工厂模式、代理模式与单例模式的介绍
java·设计模式·代理模式
糟糕好吃20 小时前
AI 全流程解析(LLM / Token / Context / RAG / Prompt / Tool / Skill / Agent)
前端·后端·设计模式
kvo7f2JTy1 天前
JAVA 设计模式
java·开发语言·设计模式
程序员小寒1 天前
JavaScript设计模式(九):工厂模式实现与应用
开发语言·前端·javascript·设计模式
LanceJiang1 天前
设计模式在前端的简易实现与作用
前端·设计模式