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
相关推荐
REDcker9 小时前
有限状态机与状态模式详解 FSM建模Java状态模式与C++表驱动模板实践
java·c++·状态模式
多加点辣也没关系9 小时前
设计模式-解释器模式
设计模式·解释器模式
basketball61610 小时前
C++ 构造函数完全指南:从入门到进阶
java·开发语言·c++
想唱rap10 小时前
IO多路转接之poll
服务器·开发语言·数据库·c++
落羽的落羽12 小时前
【算法札记】练习 | Week4
linux·服务器·数据结构·c++·人工智能·算法·动态规划
goodesocket12 小时前
芯片HAST测试:通电工作下如何精准模拟极端环境挑战?
c++
Asurplus12 小时前
23中设计模式
设计模式·创建型·结构型·行为型
特种加菲猫12 小时前
从零开始手撕AVL树:详解插入、平衡因子更新与四种旋转
开发语言·c++
萑澈12 小时前
算法竞赛入门:C++ STL核心用法与时空复杂度速查手册
数据结构·c++·算法·stl
geovindu12 小时前
go: Semaphore Pattern
开发语言·后端·设计模式·golang·企业级信号量模式