c++设计模式-观察者模式

一.概念

观察者设计模式属于行为型设计模式 ,又称发布-订阅 模式,定义了对象间的一对多依赖关系,被观察对象 状态发生变化时,所有订阅它的观察对象都会受到通知并自动更新。

二.原理

1.Subject(被观察者)

包含观察者对象的集合,提供增加、删除、通知观察者对象的抽象接口。

2.ConcreteSubject(具体的被观察者)

Subject抽象类接口的具体实现,维护观察者列表,并将变化通知所有观察者。

3.Observer(观察者)

接收Subject通知的对象,订阅Subject的状态,并提供更新操作的统一抽象接口。

4.ConcreteObserver(具体的观察者)

Observer抽象类接口的具体实现,提供了更新操作的具体实现,收到subject通知后进行更新操作。

三.特点

1.优势

  • 符合开闭原则的要求。
  • 支持广播的通信方式。
  • 动态添加观察者,代码扩展性好。

2.劣势

  • 每次状态变化都要遍历所有观察者,性能开销大。
  • 每次状态变化都要通知所有观察者,通信时间长。
  • 观察者数量过多使代码的可读性变差。

四.代码实现

1.demo1-传参通知

cpp 复制代码
#include <iostream>
#include <vector>
using namespace std;
//抽象类
class Observer {
public:
    virtual void update(int data) = 0;//纯虚函数
};

class ConcreteObserver: public Observer{
public:
    ConcreteObserver(string name)
    {
        m_sName = name;
    }

    void update(int data)
    {
        cout << m_sName << " received data:" << data << endl;
    }

private:
    string m_sName;
};

class Subject {
public:
    virtual void attach(Observer *observer) = 0;
    virtual void detach(Observer *observer) = 0;
    virtual void notify(int data) = 0;
};

class ConcreteSubject :public Subject{
public:
    void attach(Observer *observer)
    {
        observers.push_back(observer);
    }

    void detach(Observer *observer)
    {
        for(auto it=observers.begin();it!=observers.end();it++)
        {
            if(*it == observer)
            {
                observers.erase(it);
                break;
            }
        }
    }

    void notify(int data)
    {
        for(auto it=observers.begin();it!=observers.end();it++)
        {
            (*it)->update(data);
        }
    }

private:
    vector<Observer*> observers;
};

int main() {
    cout << "observer demo1!" << endl;
    ConcreteObserver observer1("observer1");
    ConcreteObserver observer2("observer2");
    ConcreteObserver observer3("observer3");

    ConcreteSubject subject;
    subject.attach(&observer1);
    subject.attach(&observer2);
    subject.attach(&observer3);
    subject.notify(10);

    subject.detach(&observer1);
    subject.notify(20);

    return 0;
}

2.demo2-模拟天气预报

cpp 复制代码
#include <iostream>
#include <vector>
using namespace std;

class Observer{
public:
    virtual void update(float temperature,float humidity,float pressure) = 0;
};

class Display:public Observer{
public:
    void update(float temperature,float humidity,float pressure){
        cout << "Temperature:" << temperature << "℃, Humidity:" << humidity << "%, Pressure:" << pressure << "hPa" << endl;
    }
};

class WeatherStation{
private:
    float m_fTemperature;
    float m_fHumidity;
    float m_fPressure;
    vector<Observer*> m_vObservers;

public:
    void attach(Observer* observer){
        m_vObservers.push_back(observer);
    }

    void detach(Observer* observer){
        for(auto it=m_vObservers.begin();it!=m_vObservers.end();it++)
        {
            if(*it == observer)
            {
                m_vObservers.erase(it);
                break;
            }
        }
    }

    void notify(){
        for(auto it=m_vObservers.begin();it!=m_vObservers.end();it++){
            (*it)->update(m_fTemperature,m_fHumidity,m_fPressure);
        }
    }

    void setValue(float temp,float hum,float press){
        m_fTemperature = temp;
        m_fHumidity = hum;
        m_fPressure = press;
        notify();
    }
};

int main() {
    std::cout << "observer demo2!" << std::endl;

    WeatherStation weatherStation;
    Display display1;
    Display display2;
    weatherStation.attach(&display1);
    weatherStation.attach(&display2);
    weatherStation.setValue(25.5,50,103);
    weatherStation.setValue(25.7,60,152);

    return 0;
}

五.运行结果

1.demo1-传参通知

bash 复制代码
observer demo1!
observer1 received data:10
observer2 received data:10
observer3 received data:10
observer2 received data:20
observer3 received data:20

2.demo2-模拟天气预报

bash 复制代码
observer demo2!
Temperature:25.5℃, Humidity:50%, Pressure:103hPa
Temperature:25.5℃, Humidity:50%, Pressure:103hPa
Temperature:25.7℃, Humidity:60%, Pressure:152hPa
Temperature:25.7℃, Humidity:60%, Pressure:152hPa
相关推荐
程与留4 小时前
15_国际化和本地化:tr()、ts 文件、QM 文件、多语言切换
c++·qt
程与留6 小时前
14_Qt 样式表(QSS)入门(语法、选择器、美化实战)
c++·qt
学习星球9 小时前
AI Agent 成本工程实战:从 OpenAI Codex 的 8 个“烧 Token“Bug 学起
人工智能·设计模式·微信小程序
欧特克_Glodon14 小时前
OpenCV计算机视觉开发入门与实践<二十七>:图像分割概述
c++·人工智能·opencv·计算机视觉
蒸蒸yyyyzwd14 小时前
cpp 选手秋招学习笔记 day21
c++·面试·八股
AI人工智能+电脑小能手1 天前
大白话说Java设计模式-46-责任链模式(业务实战篇)
java·设计模式·责任链模式·风控校验·servlet filter·spring interceptor·链式处理
WarPigs1 天前
观察者模式笔记
观察者模式
「QT(C++)开发工程师」1 天前
C++ auto 用法详解
开发语言·c++
OPEN-F1 天前
C++STL教程:容器适配器与实用工具
开发语言·c++
OPEN-F1 天前
C++模板教程:变参模板、折叠表达式与SFINAE
java·开发语言·c++