首页/文章列表/文章详情

设计模式之观察者模式(学习笔记)

编程知识1932024-07-21评论

定义

观察者模式是一种行为型设计模式,它定义了一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会收到通知并自动更新。这种模式用于实现对象之间的解耦,使得一个对象的变化可以通知并更新多个依赖对象,而无需直接引用它们。

为什么使用观察者模式?

  1. 解耦

    • 观察者模式将观察者(Observer)和被观察者(Subject)解耦,两个对象之间的依赖关系被转化为依赖接口。
  2. 动态增加观察者

    • 观察者模式允许在运行时动态增加或删除观察者,灵活性更高。
  3. 维护简便

    • 当被观察者的状态发生变化时,所有依赖对象自动更新,无需手动管理这些依赖关系,简化了维护。

实现步骤

  1. 定义抽象主题类

    • 定义一个抽象主题类,声明添加、删除观察者的方法,以及通知所有观察者的方法。
  2. 实现具体主题类

    • 实现具体主题类,包含状态变化时的通知逻辑。
  3. 定义抽象观察者类

    • 定义一个抽象观察者类,声明更新方法,具体观察者实现这个方法来更新自身状态。
  4. 实现具体观察者类

    • 实现具体观察者类,实现更新方法,根据被观察者的变化更新自身状态。

优缺点和适用场景

优点

  1. 解耦

    • 观察者与被观察者之间的耦合度降低,代码更加模块化和易于维护。
  2. 灵活性

    • 可以动态地增加或删除观察者,灵活地响应需求变化。
  3. 自动更新

    • 被观察者状态变化时,所有观察者都会自动收到通知并更新状态,无需手动调用。

缺点

  1. 可能导致性能问题

    • 如果有大量观察者,通知所有观察者可能会导致性能开销。
  2. 调试困难

    • 观察者模式涉及多个对象之间的通知和更新,可能会导致调试变得复杂。

适用场景

  1. 事件处理系统

    • 例如 GUI 事件处理系统,当用户触发某个事件时,所有相关的处理函数都需要被通知。
  2. 模型-视图-控制器(MVC)架构

    • 模型(Model)作为被观察者,视图(View)作为观察者,当模型的数据发生变化时,视图会自动更新显示。
  3. 订阅-发布系统

    • 允许对象订阅事件并在事件发生时接收通知,实现松耦合的事件处理机制。

例子:股票市场

假设我们有一个股票市场系统,当某只股票的价格变化时,所有关注这只股票的投资者都会收到通知。我们可以使用观察者模式来实现这一功能。
#include <iostream>#include<vector>#include<memory>//抽象观察者类:投资者class Investor {public:virtual~Investor() {} virtualvoidupdate(double price) = 0;};//具体观察者类:具体投资者class ConcreteInvestor : public Investor {private: std::stringname;public: ConcreteInvestor(conststd::string& name) : name(name) {} voidupdate(doubleprice)override { std::cout <<"Investor" << name << " is notified. New stock price: " << price << std::endl; }};//抽象主题类:股票class Stock {public:virtual~Stock() {} virtualvoid addObserver(std::shared_ptr<Investor> investor) = 0;virtualvoid removeObserver(std::shared_ptr<Investor> investor) = 0;virtualvoid notifyObservers() = 0;};//具体主题类:具体股票class ConcreteStock : public Stock {private: std::vector<std::shared_ptr<Investor>>investors;doubleprice;public:void addObserver(std::shared_ptr<Investor> investor) override { investors.push_back(investor); } void removeObserver(std::shared_ptr<Investor> investor) override { investors.erase(std::remove(investors.begin(), investors.end(), investor), investors.end()); } voidnotifyObservers()override{for(constauto& investor : investors) { investor->update(price); } } voidsetPrice(double newPrice) { price = newPrice; notifyObservers(); }};int main() { //创建具体股票 std::shared_ptr<ConcreteStock> stock = std::make_shared<ConcreteStock>();//创建具体投资者 std::shared_ptr<Investor> investor1 = std::make_shared<ConcreteInvestor>("Alice"); std::shared_ptr<Investor> investor2 = std::make_shared<ConcreteInvestor>("Bob");//添加投资者到股票的观察者列表中stock->addObserver(investor1); stock->addObserver(investor2);//修改股票价格stock->setPrice(100.0); stock->setPrice(105.0);return0;}

 

神弓

博客园

这个人很懒...

用户评论 (0)

发表评论

captcha