c++设计模式之观察者模式(发布-订阅模式)

介绍

观察者模式主要关注于对象的一对多关系,其中多个对象都依赖于一个对象,当该对象的状态发生改变时,其余对象都能接收到相应的通知。

如,现在有

  • 一个数据对象
  • 三个画图对象,分别wield曲线图、柱状图、饼状图三个对象
  • 三个画图对象都依赖于数据对象的数据
  • 而观察者模式要做的是,当数据对象的数据发生改变时,依赖数据对象的曲线图、柱状图、饼状图对象的图形都要及时作出改变

案例

  • 定义三个obsever对象,和一个subject对象
  • 每个observer对象都对subject对象的一个或者多个消息感兴趣
  • 当subject对象的数据状态发生改变时,应及时通知对应的观察者,并作出改变

observer类


//观察者抽象类
class Observer
{
public:
    //观察者消息处理函数
    virtual void handler(int msgid)=0;
};

//第一个观察者实例
class Observer1:public Observer
{
public:
    void handler(int msgid)
    {
    //第一个观察者对消息1和消息2感兴趣,
    //当消息1或者消息2的状态发生改变时,该观察者作出对应的响应
        switch(msgid)
        {
            case 1:
                cout<<"observer1 recv msg 1"<<endl;
                break;
            case 2:
                cout<<"observer1 recv msg 2"<<endl;
                break;
            default:
                cout<<"oberver1 recv unknow msg!"<<endl;
                break;
        }
    }
};

//第二个观察者实例
class Observer2:public Observer{
public:
    void handler(int msgid)
    {
        switch(msgid)
        {

            case 2:
                cout<<"observer2 recv msg 2"<<endl;
                break;
            default:
                cout<<"oberver2 recv unknow msg!"<<endl;
                break;
        }
    }
};

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

subject类


//主题类
class Subject
{
public:
    //将观察者及其所感兴趣的消息添加到map中
    void addOberver(Observer* obser,int msgid)
    {
        _subMap[msgid].push_back(obser);
    }

    //检测到感兴趣的消息发生了改变,就及时通知对应的观察者
    void dispatch(int msgid)
    {
        auto it=_subMap.find(msgid);//寻找该消息对应的观察者
        if(it!=_subMap.end())
        {
            for(Observer* obser:it->second)
            {
                obser->handler(msgid);//将发生的消息发送给对应的观察者
            }
        }
    }
private:
    //int:消息id;list<Observer*>:对该消息感兴趣的观察者
    /*即每一个消息都有其对应感兴趣的观察者*/
    unordered_map<int,list<Observer*>> _subMap;
};

测试


void test()
{
    Observer* p1=new Observer1;
    Observer* p2=new Observer2;
    Observer* p3=new Observer3;

    Subject sub;
    //注册观察者及其感兴趣的消息
    //第一个观察者对消息1和消息2感兴趣
    sub.addOberver(p1,1);
    sub.addOberver(p1,2);
    //第二个观察者对消息2感兴趣
    sub.addOberver(p2,2);
    //第三个观察者对消息1和消息3感兴趣
    sub.addOberver(p3,1);
    sub.addOberver(p3,3);

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

}

相关推荐

  1. c++设计模式观察模式(消息订阅模式

    2024-02-02 12:30:01       34 阅读
  2. C++ 设计模式观察模式

    2024-02-02 12:30:01       51 阅读
  3. js设计模式--发布订阅模式

    2024-02-02 12:30:01       39 阅读
  4. 发布订阅模式观察模式详解

    2024-02-02 12:30:01       55 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-02-02 12:30:01       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-02-02 12:30:01       100 阅读
  3. 在Django里面运行非项目文件

    2024-02-02 12:30:01       82 阅读
  4. Python语言-面向对象

    2024-02-02 12:30:01       91 阅读

热门阅读

  1. EasyExcel实现三级联动

    2024-02-02 12:30:01       47 阅读
  2. K8S-PV 与PVC

    2024-02-02 12:30:01       53 阅读
  3. Unity_Render Pipeline

    2024-02-02 12:30:01       47 阅读
  4. Python 方法重载

    2024-02-02 12:30:01       48 阅读
  5. 开源软件:颠覆创新的力量

    2024-02-02 12:30:01       53 阅读
  6. 开源软件的崛起:塑造产业未来

    2024-02-02 12:30:01       54 阅读
  7. Linux上使用OpenCvSharp

    2024-02-02 12:30:01       62 阅读
  8. 多个MP3音频合成

    2024-02-02 12:30:01       53 阅读
  9. FFmpge命令记录

    2024-02-02 12:30:01       48 阅读
  10. 【Spring Boot 3】应用启动执行特定逻辑

    2024-02-02 12:30:01       39 阅读
  11. vba 获取指定单元格value

    2024-02-02 12:30:01       51 阅读
  12. 算法专题:记忆搜索

    2024-02-02 12:30:01       46 阅读
  13. 每日算法打卡:动态求连续区间和 day 31

    2024-02-02 12:30:01       59 阅读
  14. 详解 Kruskal 算法的实现

    2024-02-02 12:30:01       54 阅读