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

介绍

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

如,现在有

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

案例

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

observer类

cpp 复制代码
//观察者抽象类
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类

cpp 复制代码
//主题类
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;
};

测试

cpp 复制代码
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:";
    }

}
相关推荐
ffcf12 小时前
设计模式—专栏简介
设计模式
tianchang14 小时前
SSR 深度解析:从原理到实践的完整指南
前端·vue.js·设计模式
饕餮争锋15 小时前
设计模式笔记_创建型_建造者模式
笔记·设计模式·建造者模式
小小寂寞的城16 小时前
JAVA策略模式demo【设计模式系列】
java·设计模式·策略模式
一块plus18 小时前
深度详解 Revive 和 Precompile 技术路径
后端·设计模式·架构
智想天开20 小时前
31.设计模式的反模式与常见误区
设计模式
小飞悟21 小时前
组件通信的艺术:从 props 钻井到 context 共享的进化之路
前端·javascript·设计模式
Point21 小时前
[ahooks] useEventEmitter源码阅读
前端·javascript·设计模式
鸡蛋灌Bean1 天前
Java常用设计模式大全
java·开发语言·设计模式
喝可乐的布偶猫1 天前
Java-----韩顺平单例设计模式学习笔记
java·笔记·设计模式