首页 > 其他分享 >设计模式之观察者模式(学习笔记)

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

时间:2024-07-21 17:09:34浏览次数:14  
标签:std investors void 观察者 笔记 shared 设计模式 investor

定义

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

为什么使用观察者模式?

  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() {}
    virtual void update(double price) = 0;
};


// 具体观察者类:具体投资者
class ConcreteInvestor : public Investor {
private:
    std::string name;
public:
    ConcreteInvestor(const std::string& name) : name(name) {}
    void update(double price) override {
        std::cout << "Investor " << name << " is notified. New stock price: " << price << std::endl;
    }
};


// 抽象主题类:股票
class Stock {
public:
    virtual ~Stock() {}
    virtual void addObserver(std::shared_ptr<Investor> investor) = 0;
    virtual void removeObserver(std::shared_ptr<Investor> investor) = 0;
    virtual void notifyObservers() = 0;
};


// 具体主题类:具体股票
class ConcreteStock : public Stock {
private:
    std::vector<std::shared_ptr<Investor>> investors;
    double price;
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());
    }
    void notifyObservers() override {
        for (const auto& investor : investors) {
            investor->update(price);
        }
    }
    void setPrice(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);


    return 0;
}

 

标签:std,investors,void,观察者,笔记,shared,设计模式,investor
From: https://www.cnblogs.com/best-doraemon/p/18314669

相关文章

  • 圆方树学习笔记 & 最短路 题解
    前言圆方树学习笔记,从一道例题讲起。题目链接:Hydro&bzoj。题意简述仙人掌上求两点距离。题目分析为了把仙人掌的性质发挥出来,考虑将其变成一棵树。圆方树就是这样转换的工具。先讲讲圆方树的概念:原图上的点为圆点,每个点双对应一个方点,树边都是方点连向点双内的圆点。具......
  • 概率与计算 ----学习笔记
    概率与计算(定理、推论集合)Chapter\(I\)概率论公理定义\(1.1\) 概率空间三要素  \(1.\)样本空间\(\Omega\),限制在概率空间上的随机过程所以可能结果的集合  \(2.\)表示可容许事件的族集\(\mathcal{F}\),其中\(\mathcal{F}\)中的每个集合都是样本空间\(\Omeg......
  • Java 随笔记: 集合与泛型
    文章目录1.集合框架概述2.集合接口2.1Collection接口2.2List接口2.3Set接口2.4Map接口3.集合的常用操作3.1添加元素3.2删除元素3.3遍历元素3.4判断大小3.5判断是否为空4.迭代器4.1迭代器的作用4.2迭代器的使用4.3迭代器与增强for循环4.4迭代器......
  • MCCM论文阅读笔记
    ImprovingNewsRecommendationwithChannel-WiseDynamicRepresentationsandContrastiveUserModeling论文阅读笔记Abstract存在的问题:​ 现有方法大多使用CNN和Self-Attention等深度学习模型从新闻标题和摘要中提取文本特征,生成特定的新闻向量。然而,基于CNN的方法......
  • sql修炼笔记——基础操作指南篇
    基础操作指南1.新建数据库createdatabase·名称·(使用的是反引号,后者皆同)2.展示,showdatabases展示全部数据表3.数据类型INT --整数decimal(m,n)--有小数点的数如decimal(3,2)共三位数小数点占两位,如2.33varchar(n)最多存放n个字符blobBinarylargeobject图片影片档......
  • 失败笔记本--HALCON--009--202407
    失败笔记本-HALCON篇-009项目场景:今天还是和大佬学习的一天,今儿个学习怎么识别图中的颜色块,实现下面的效果:识别到图中的颜色块的颜色,并显示在图中。参考大神的链接:halcon入门教程10_颜色识别11.通过颜色灰度识别图中的颜色步骤:上来我就是一套丝滑小连招啊,打开图片,......
  • 俊昭c语言笔记
    c语言——指针c语言——指针-CSDN博客c语言——函数格式和语句c语言——函数格式和语句_c语言副函数格式-CSDN博客c语言——break和continuec语言——break和continue_break的作用c语言-CSDN博客c语言——常用的输出函数c语言——常用的输出函数-CSDN博客c语言——运算符c......
  • Debian12 AMD 显卡 7900XT 安装使用 stable-diffusion-webui 笔记
    简介由于AMD官方没有提供Debian12的驱动和ROCM,只好安装Ubuntu20.04的驱动和ROCM,必要软件git和python3-venv。添加i386仓库sudodpkg--add-architecturei386&&\sudoaptupgrade-y&&\aptupgrade-y下载驱动安装程序到AMD官网下载Ubuntu20.04驱动......
  • 『数学记录』概率导论学习笔记(二):随机变量
      本文为DimitriP.Bertsekas与JohnN.Tsitsiklis所著的《概率导论》的学习笔记。  由于时间紧迫,过于详细的举例说明会导致自己的学习效率较低,于是本文将会比上一篇略去非常多不必要的举例与解释,同时加入很多名词的英文单词,利于以后更好地对外文著作及论文的学习。Part1 ......
  • Datawhale AI夏令营学习笔记 (3)
        在上一篇DatawhaleAI夏令营学习笔记(2)-CSDN博客中我们尝试使用了机器学习的方法进行回归预测。本篇,我们分为两个方面来探索。一方面,我们将继续使用机器学习的方法,在原有的数据上做更多特征工程,在预测上我们使用更多的算法模型。另一方面,我们尝试使用深度学习的方......