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:";
    }

}
相关推荐
编程、小哥哥1 分钟前
设计模式之代理模式(模拟mybatis-spring中定义DAO接口,使用代理类方式操作数据库原理实现场景)
设计模式·mybatis·代理模式
白茶等风121381 小时前
Unity 设计模式-状态模式(State Pattern)详解
设计模式·状态模式
好好学习++1 小时前
【HF设计模式】01-策略模式
java·c++·设计模式·策略模式
zzzhpzhpzzz1 小时前
设计模式——状态模式
设计模式·状态模式
oioihoii2 小时前
建造者模式
c++·设计模式·c#·建造者模式
暗夜绿2 小时前
【GoF23种设计模式】01_建造者模式
java·设计模式·建造者模式
夏旭泽2 小时前
设计模式-建造者模式
设计模式·建造者模式
无敌岩雀2 小时前
C++设计模式行为模式———状态模式
c++·设计模式·状态模式
孤华暗香3 小时前
Python设计模式详解之14 —— 命令模式
python·设计模式·命令模式
岳轩子4 小时前
23种设计模式之单例模式
java·单例模式·设计模式