设计模式——观察者模式

定义

观察者模式(Observer Pattern)是一种行为型设计模式。它定义了一种一对多的依赖关系,让多个观察者对象(Observer)同时监听一个主题对象(Subject)。当主题对象的状态发生变化时,它会通知所有依赖它的观察者对象,观察者对象会根据主题对象状态的变化做出相应的反应。

UML 类图及主要角色

  • 抽象主题(Subject):
    它是被观察的对象,一般是一个抽象类或接口。它维护了一个观察者对象的列表,并且提供了添加、删除观察者对象的方法,同时还包括一个通知所有观察者对象的抽象方法。
  • 具体主题(Concrete Subject):
    实现了抽象主题中的方法。它管理主题对象的状态,当状态发生变化时,它会调用通知方法来告知所有的观察者对象。
  • 抽象观察者(Observer):
    定义了一个抽象的更新方法,当接收到主题对象的通知时,观察者对象通过这个方法来更新自己的状态。
  • 具体观察者(Concrete Observer):
    实现了抽象观察者的更新方法。每个具体观察者对象根据自己的需求来处理主题对象状态变化的信息。

简单示例:新闻发布系统

  • 抽象主题类
cpp 复制代码
class NewsSubject {
public:
  virtual ~NewsSubject() {}
  virtual void attach(Observer* observer) = 0;
  virtual void detach(Observer* observer) = 0;
  virtual void notify() = 0;
};
  • 具体主题类
cpp 复制代码
class NewsAgency : public NewsSubject {
private:
  std::vector<Observer*> observers;
  std::string news;
public:
  void attach(Observer* observer) override {
    observers.push_back(observer);
  }
  void detach(Observer* observer) override {
    auto it = std::find(observers.begin(), observers.end(), observer);
    if (it!= observers.end()) {
      observers.erase(it);
    }
  }
  void notify() override {
    for (Observer* observer : observers) {
      observer->update(news);
    }
  }
  void setNews(const std::string& n) {
    news = n;
    notify();
  }
};
  • 抽象观察者类
cpp 复制代码
class Observer {
public:
  virtual ~Observer() {}
  virtual void update(const std::string& news) = 0;
};

具体观察者类

cpp 复制代码
class NewsReader : public Observer {
private:
  std::string name;
public:
  NewsReader(const std::string& n) : name(n) {}
  void update(const std::string& news) override {
    std::cout << name << " received news: " << news << std::endl;
  }
};

使用示例

cpp 复制代码
int main() {
  NewsAgency agency;
  NewsReader reader1("Reader1");
  NewsReader reader2("Reader2");
  agency.attach(&reader1);
  agency.attach(&reader2);
  agency.setNews("Breaking news: A new discovery!");
  agency.detach(&reader1);
  agency.setNews("Another news: Technology update.");
  return 0;
}

在这个示例中,NewsSubject是抽象主题,NewsAgency是具体主题,它管理新闻内容并且通知观察者。Observer是抽象观察者,NewsReader是具体观察者,它接收新闻并进行显示。

优点

  • 松耦合:
    主题和观察者之间是松耦合的关系。主题对象不需要知道观察者对象的具体细节,只需要在状态变化时通知它们即可。同样,观察者对象也只需要实现更新方法来处理主题对象状态变化的信息,不需要了解主题对象内部是如何维护状态的。
  • 可扩展性好:
    可以很容易地添加新的观察者对象,只要实现抽象观察者的更新方法即可。在上述新闻发布系统的例子中,如果要添加新的新闻读者,只需要创建一个新的NewsReader对象并将其添加到NewsAgency中。

缺点

  • 可能会导致过多的通知开销:
    如果有大量的观察者对象,并且主题对象的状态频繁变化,那么通知所有观察者对象会产生较大的开销,可能会影响系统的性能。
  • 可能存在循环依赖问题:
    在复杂的系统中,如果观察者对象和主题对象之间存在循环依赖关系,可能会导致系统的逻辑混乱,难以维护。不过,通过合理的设计和分层可以尽量避免这种情况。
相关推荐
OPEN-F4 分钟前
ROS2系列教程:Gazebo插件(关节控制/IMU/激光雷达)
c++·python·数码相机·算法·机器人
luj_176811 分钟前
虚实交融中的真实人物塑造
c语言·开发语言·网络·经验分享·算法
haolin123.41 分钟前
STL vector底层揭秘:从构造到迭代器失效
开发语言·c++·算法
shehuiyuelaiyuehao1 小时前
算法37,位运算,两个整数之和(不用+符号)
算法
2401_868534781 小时前
网规备考_2.4 路由协议
c++·设计模式
猎头南楼1 小时前
MFC 质量流量控制器中的控制算法设计与落地思考
人工智能·算法
来一碗刘肉面1 小时前
平衡二叉树的删除
数据结构·算法
wabs6661 小时前
关于二叉树【力扣199.二叉树的右视图的思考】
数据结构·c++·算法·leetcode·二叉树·层序遍历
a187927218311 小时前
【算法】动态规划第三篇:背包第一课——贪心之死与正序倒序开关
算法·leetcode·动态规划·贪心·dp·暴力·算法讲解
黄金龙PLUS1 小时前
Xoodoo置换算法的优缺点
算法·网络安全·密码学·哈希算法·同态加密