首页 > 编程语言 >用C++11打造智能观察者模式:详解实现步骤完整示例代码

用C++11打造智能观察者模式:详解实现步骤完整示例代码

时间:2024-01-25 09:13:13浏览次数:35  
标签:11 Observer 示例 void 主题 观察者 C++ include data

 

观察者模式是一种行为设计模式,其中一个对象(主题)维护其依赖对象(观察者)的列表,当主题的状态发生变化时,它通知所有观察者。以下是一个使用C++11实现观察者模式的简单例子:

  1. 定义观察者接口(Observer): 创建一个观察者接口,该接口包含观察者需要实现的更新方法。这个接口可以包含其他方法,但更新方法是必须的。
  2. 创建具体观察者类: 实现观察者接口的具体类。每个具体观察者类都应该实现更新方法,该方法定义了在主题状态变化时观察者应该执行的操作。
  3. 定义主题接口(Subject): 创建一个主题接口,该接口包含了添加、移除和通知观察者的方法。这里可以选择在主题接口中定义更新状态的方法,也可以在具体主题类中定义。
  4. 创建具体主题类: 实现主题接口的具体类。该类应该维护一个观察者列表,并在状态变化时通知所有观察者。
  5. 实现客户端代码: 在客户端代码中创建具体的主题和观察者对象,将观察者添加到主题中。客户端还负责触发主题状态的变化,从而通知观察者。

下面是对上述步骤的更详细的讲解:

步骤 1:定义观察者接口

// Observer.h
#pragma once

class Observer {
public:
    virtual void update(int data) = 0;
};

步骤 2:创建具体观察者类

// ConcreteObserverA.h
#pragma once
#include <iostream>
#include "Observer.h"

class ConcreteObserverA : public Observer {
public:
    void update(int data) override {
        std::cout << "Observer A 收到更新,数据为: " << data << std::endl;
    }
};
// ConcreteObserverB.h
#pragma once
#include <iostream>
#include "Observer.h"

class ConcreteObserverB : public Observer {
public:
    void update(int data) override {
        std::cout << "Observer B 收到更新,数据为: " << data << std::endl;
    }
};

步骤 3:定义主题接口

// Subject.h
#pragma once
#include "Observer.h"

class Subject {
public:
    virtual void addObserver(Observer* observer) = 0;
    virtual void removeObserver(Observer* observer) = 0;
    virtual void notifyObservers(int data) = 0;
};

步骤 4:创建具体主题类

// ConcreteSubject.h
#pragma once
#include <vector>
#include "Subject.h"

class ConcreteSubject : public Subject {
private:
    std::vector<Observer*> observers;
    int data;

public:
    void addObserver(Observer* observer) override {
        observers.push_back(observer);
    }

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

    void notifyObservers(int data) override {
        for (Observer* observer : observers) {
            observer->update(data);
        }
    }

    void setData(int newData) {
        data = newData;
        notifyObservers(data);
    }

    int getData() const {
        return data;
    }
};

步骤 5:实现客户端代码

// main.cpp
#include "ConcreteObserverA.h"
#include "ConcreteObserverB.h"
#include "ConcreteSubject.h"

int main() {
    ConcreteSubject subject;
    ConcreteObserverA observerA;
    ConcreteObserverB observerB;

    subject.addObserver(&observerA);
    subject.addObserver(&observerB);

    subject.setData(123);

    subject.removeObserver(&observerA);

    subject.setData(456);

    return 0;
}

在这个例子中,我们创建了抽象观察者类 Observer,具体观察者类 ConcreteObserverA 和 ConcreteObserverB。然后,我们定义了抽象主题类 Subject 和具体主题类 ConcreteSubject。最后,在客户端代码中,我们创建了具体的主题和观察者对象,将观察者添加到主题中,并演示了状态变化时如何通知观察者,以及如何移除观察者。

 

标签:11,Observer,示例,void,主题,观察者,C++,include,data
From: https://www.cnblogs.com/hanbing81868164/p/17986284

相关文章

  • 1. C++ 开发环境
    C++开发环境VisualC++/GCC(G++)/Clang(Clang++)集成开发环境:VisualStudio/CodeLite/Code::blocks/CLion/Eclipse...工具:/usr/bin/timevalgrindcppreferenceCompilerexplorerC++Insights当前各版本编译器对C++20特性的支持情况:查看网站:https://......
  • C/C++ 常用输出流
    在程序设计中,数据输入/输出(I/O)操作是必不可少的,C++语言的数据输入/输出操作是通过I/O流库来实现的。C++中把数据之间的传输操作称为流,流既可以表示数据从内存传送到某个载体或设备中,即输出流,也可以表示数据从某个载体或设备传送到内存缓冲区变量中,即输入流。C++流涉及以下概念:标......
  • KY124 二叉搜索树C++
    先把BST建立起,然后递归遍历判断树就好了。#include<iostream>#include<string>usingnamespacestd;structnode{chardata;structnode*left;structnode*right;};typedefstructnodetree;tree*build(strings){inti=0;tree*root=NULL......
  • NanoFramework操作ESP32(一)_基础元器件篇(二十二)_DHT11温湿度传感器
    一、元器件介绍1、针脚用途编号名称功能1VCC电源正2TRIG触发控制信号输入3ECHO回响信号输出4GND电源地2、电气参数 二、示例代码1、代码:元器件的针脚ESP32模块的针脚VCC;供电脚+5VTRIG;发送脚IO17ECHO;接收脚IO16GND......
  • KY207 二叉排序树C++
    考二叉搜索树的插入。#include<iostream>usingnamespacestd;structnode{intdata;structnode*left;structnode*right;};typedefstructnodetree;intmain(){intn;while(cin>>n){tree*root=NULL;while(n!=0......
  • KY11 二叉树遍历C++
    这个题目思路其实就是先序遍历的变形。相当于沿着先序遍历的顺序跟着构建二叉树就行。然后中序遍历这个树。#include<iostream>#include<string>usingnamespacestd;structtnode{chardata;structtnode*left;structtnode*right;};typedefstructt......
  • KY212 二叉树遍历C++
    思路是先构造出树,然后在后序遍历整个树。#include<iostream>#include<string>usingnamespacestd;structTnode{chardata;structTnode*left;structTnode*right;};typedefstructTnodeTree;Tree*build(stringpre,inth1,intt1,stringin,inth2......
  • CF-1184-E3-最小生成树+倍增+并查集
    1184-E3题目大意给定一个\(n\)个点,\(m\)条边的无向图,边带权。对于每条边,你需要找到最大值\(x\),使得把这条边的权值修改为\(x\)后能够出现在最小生成树上。Solution先把整个图的最小生成树弄出来,然后将边分为树边以及非树边来考虑:非树边:对于一个非树边连接了\(x\)和\(y\)的......
  • windwos10-11打开任意文件弹出警告
    如下打开exe或者视频、图片都弹出警告解决方案输入快捷键win+s换出搜索框输入Internet选项进入安全选项点击自定义级别找到,加载应用程序和不安全文件勾选启用(不安全)然后确定-在点击应用即可......
  • std::function类的使用示例
    std::function是C++标准库中的一个模板类,用于封装可调用的目标,比如函数、函数指针、成员函数指针、Lambda表达式等,使得它们可以像普通函数一样被调用。这种灵活性使得std::function在许多场景下都非常有用。以下是std::function的一般用法:1.封装函数指针1.1不带参数和返回值......