[C/C++] -- 观察者模式

观察者模式是一种行为型设计模式,用于定义对象间的一种一对多的依赖关系,使得当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。

观察者模式涉及以下几个角色:

  1. 主题(Subject):也称为被观察者或可观察对象,它维护一系列依赖于它的观察者对象,并提供添加、删除和通知观察者的方法。
  2. 观察者(Observer):定义了一个更新接口,以便在主题状态发生改变时接收通知。
  3. 具体主题(Concrete Subject):实现了主题接口,负责维护观察者列表以及状态变化时通知观察者。
  4. 具体观察者(Concrete Observer):实现了观察者接口,在接收到主题通知时进行相应的更新操作。

观察者模式的核心思想是解耦主题和观察者,使得它们可以独立地变化。主题不需要知道观察者的具体类型和数量,只需要维护一个观察者列表,并在状态变化时通知这些观察者即可。这种松耦合的设计使得系统更加灵活和可扩展。

#include <iostream>
#include <string>
#include <memory>
#include <unordered_map>
#include <list>
using namespace std;

/*
行为型模式:主要关注的是对象之间的通信。
观察者-监听者模式(发布-订阅模式)设计模式:主要关注的是对象的一对多的关系,也就是多个对象
都依赖一个对象,当该对象的状态发生改变时,其它对象都能够接收到相应的通知。

一组数据(对象) -》通过这一组数据-》 曲线图(对象1)/柱状图(对象2)/圆饼图(对象3)
当数据对象改变时,对象1、对象2、对象3应该及时的收到相应的通知!

Observer1   Observer2   Observer3

    Subject(主题) 主题有更改,应该及时通知相应的观察者,去处理相应的事件
*/
class Observer // 观察者抽象类
{
public:
    // 处理消息的接口
    virtual void handle(int msgid) = 0;
};

// 第一个观察者实例
class Observer1 : public Observer
{
public:
    void handle(int msgid)
    {
        switch (msgid)
        {
        case 1:
            cout << "Observer1 recv 1 msg!" << endl;
            break;
        default:
            break;
        }
    }
};

// 第二个观察者实例
class Observer2 : public Observer
{
public:
    void handle(int msgid)
    {
        switch (msgid)
        {
        case 2:
            cout << "Observer2 recv 2 msg!" << endl;
            break;
        default:
            break;
        }
    }
};

// 第三个观察者实例
class Observer3 : public Observer
{
public:
    void handle(int msgid)
    {
        switch (msgid)
        {
        case 1:
            cout << "Observer3 recv 1 msg!" << endl;
            break;
        case 2:
            cout << "Observer3 recv 2 msg!" << endl;
            break;
        case 3:
            cout << "Observer3 recv 3 msg!" << endl;
            break;
        default:
            break;
        }
    }
};

class Subject // 主题抽象类
{
public:
    void addObserver(Observer* observer,int msgid)
    {
        _subMap[msgid].push_back(observer);
        /*
        auto it = _subMap.find(msgid);
        if(it!=_subMap.end())
        {
            it->second.push_back(observer);
        }
        else
        {
            list<Observer*> li;
            li.push_back(observer);
            _subMap.insert({msgid,li});
        }
        */
    }
    //主题检测发生改变,通知相应的观察者对象处理事件
    void dispatch(int msg)
    {
        auto it = _subMap.find(msg);
        if(it!=_subMap.end())
        {
            for(Observer *obs : it->second)
            {
                obs->handle(msg);
            }
        }
    }

private:
    unordered_map<int,list<Observer*>> _subMap;
};

int main()
{
    Subject sub;
    Observer *p1 = new Observer1();
    Observer *p2 = new Observer2();
    Observer *p3 = new Observer3();

    sub.addObserver(p1,1);
    sub.addObserver(p2,2);
    sub.addObserver(p3,1);
    sub.addObserver(p3,2);
    sub.addObserver(p3,3);

    int msgid = 0;
    for(;;)
    {
        cout<<"输入消息id:";
        cin>>msgid;
        if(msgid==-1)
            break;
        sub.dispatch(msgid);
    }
    return 0;
}

上一篇:独有病眼花,春风吹不落。 (二维坐标压缩成一个点,并查集)


下一篇:微服务----nacos配置及简单使用