C++ 设计模式:观察者模式(Observer Pattern)

链接:C++ 设计模式
链接:C++ 设计模式 - 模板方法
链接:C++ 设计模式 - 策略模式

观察者模式(Observer Pattern)是一种行为设计模式,它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。当主题对象的状态发生变化时,它会通知所有观察者对象,使它们能够自动更新。

1.问题分析

在开发中,经常会遇到需要在一个对象状态变化时通知其他对象的情况。如果将通知逻辑直接嵌入到主题对象中,会导致代码耦合度高,难以维护和扩展。观察者模式通过将观察者对象和主题对象解耦,使得它们可以独立变化。

2.实现步骤

  1. 定义观察者接口:定义一个接口,包含更新方法。
  2. 定义主题接口:定义一个接口,包含注册、注销和通知观察者的方法。
  3. 实现具体主题类:具体主题类实现主题接口,并维护一个观察者列表。
  4. 实现具体观察者类:具体观察者类实现观察者接口,并在更新方法中实现具体的响应逻辑。

3.代码示例

以机器人电池电量作为示例:

3.1.观察者接口

cpp 复制代码
// 定义更新方法
class Observer {
 public:
  virtual ~Observer() = default;
  virtual void update(int batteryLevel) = 0;
};

3.2. 主题接口

cpp 复制代码
// 定义添加、删除和通知观察者的方法
class Subject {
 public:
  virtual ~Subject() = default;
  virtual void addObserver(std::shared_ptr<Observer> observer) = 0;
  virtual void removeObserver(std::shared_ptr<Observer> observer) = 0;
  virtual void notifyObservers() = 0;
};

3.3.具体主题类

cpp 复制代码
// 实现主题接口
class Robot : public Subject {
 public:
  void addObserver(std::shared_ptr<Observer> observer) override { observers.push_back(observer); }

  void removeObserver(std::shared_ptr<Observer> observer) override {
    observers.erase(std::remove(observers.begin(), observers.end(), observer), observers.end());
  }

  void notifyObservers() override {
    for (const auto& observer : observers) {
      observer->update(batteryLevel);
    }
  }

  void setBatteryLevel(int level) {
    batteryLevel = level;
    notifyObservers();
  }

 private:
  std::vector<std::shared_ptr<Observer>> observers;
  int batteryLevel = 100;
};

3.4.具体观察者类

cpp 复制代码
// 具体观察者类1,显示电池电量
class BatteryDisplay : public Observer {
 public:
  void update(int batteryLevel) override { std::cout << "BatteryDisplay: Battery level is " << batteryLevel << "%" << std::endl; }
};
cpp 复制代码
// 具体观察者类2,当电池电量低于20%时发出警告
class BatteryWarning : public Observer {
 public:
  void update(int batteryLevel) override {
    if (batteryLevel < 20) {
      std::cout << "BatteryWarning: Warning - Battery level low (" << batteryLevel << "%)" << std::endl;
    }
  }
};

3.5.调用算法

cpp 复制代码
int main() {
  auto robot = std::make_shared<Robot>();
  auto batteryDisplay = std::make_shared<BatteryDisplay>();
  auto batteryWarning = std::make_shared<BatteryWarning>();

  robot->addObserver(batteryDisplay);
  robot->addObserver(batteryWarning);

  std::cout << "Setting battery level to 50%" << std::endl;
  robot->setBatteryLevel(50);

  std::cout << "\nSetting battery level to 15%" << std::endl;
  robot->setBatteryLevel(15);

  return 0;
}
相关推荐
豆沙沙包?1 小时前
C++~~~set容器、map容器(p57-P69)
开发语言·c++
qeen871 小时前
【数据结构】哈希表的C++实现与封装
数据结构·c++·散列表·哈希表
乐观勇敢坚强的老彭3 小时前
C++信奥GESP四级的常见题型和解题模板速查表
开发语言·c++
欧特克_Glodon3 小时前
OpenCV计算机视觉开发入门与实践<二十二>:图像平滑之线性滤波
c++·人工智能·opencv·计算机视觉
沙盘客4 小时前
AFSIM 示例解读(09)· 传感器全家桶 sensor_demos(下):ESM / SAR / 被动测向
c++·经验分享·后端
大鹏的NLP博客4 小时前
WSL2 资源治理:从 ONNX Runtime CUDA 编译 OOM 到 `.wslconfig` 防御配置
c++·深度学习·onnx runtime
星星.7224 小时前
C++算法竞赛|二分查找与二分答案:边界模板、浮点二分、STL
数据结构·c++·算法
bryant_meng5 小时前
【Codex】Part 19 — Codex Prompt Design Patterns
设计模式·prompt·playbook·结果优先·用证据定义完成
老当益壮梁奶奶5 小时前
Linux 软件编程学习笔记(六):线程编程入门与实践
linux·c语言·c++·笔记·学习
小小龙学IT5 小时前
Dear ImGui 开源即时模式 GUI 库深度解析
c++·ui·开源