C++中的观察者设计模式

C++中的观察者设计模式

1.观察者设计模式

​ 观察者设计模式:就用来解决两个不相关对象之间的一对一或一对多的通信模型。

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

​ 在观察者模式中,主体是通知的发布者,它发出通知时并不需要知道谁是它的观察者,可以有任意数目的观察者订阅并接收通知。观察者模式不仅被广泛应用于软件界面元素之间的交互,在业务对象之间的交互、权限管理等方面也有广泛的应用。

​ 观察者模式(Observer)完美的将观察者和被观察的对象分离开。观察者模式在模块之间划定了清晰的界限,提高了应用程序的可维护性和重用性。

2.应用场景

​ 观察者设计模式定义了对象间的一种一对多的组合关系,以便一个对象的状态发生变化时,所有依赖于它的对象都得到通知并自动刷新。

​ 观察者和被观察者之间存在“观察”的逻辑关联,当被观察者发生改变的时候,观察者就会观察到这样的变化,并且做出相应的响应。

3编程套路

​ 1.设定两者类,一个为观察者类(接收者),一个为被观察者类(信号的发出者)。

​ 2.观察者类(接收者)中,定义一个对某个事件感兴趣的处理函数,一般也叫槽函数。

​ 3.被观察者(信号的发出者)类中,定义一个数据结构,用来保存观察者对哪一个事件id(信号)感兴趣,使用数据结构建立信号与对象之间的映射关系。

​ 4.被观察者类中,定义两个方法函数:

​ 一个方法为:添加观察者与其感兴趣的事件id(信号)加入到容器之中。

​ 另一个方法为:信号函数:通知事件函数执行逻辑:首先遍历容器之中,有没有感兴趣的事件ID,如果有,则代表一系列的观察者,对这个事件感兴趣,那么再次遍历观察者列表,让每一个观察者执行相应的槽函数。

4.代码实现

#include <iostream>
#include <map>
#include <list>
using namespace std;
class Recvbase{
public:
    //定义槽函数
    virtual void solt_function(int msgid = 0)=0;
    virtual ~Recvbase() = default;
};
class Recv:public Recvbase{
public:
    //实现槽函数的逻辑
    void solt_function(int msgid ) override{
        switch(msgid){
        case 1:
            cout << "接收到了信号id 1,并开始执行1的逻辑" << endl;
            break;
        case 2:
            cout << "接收到了信号id 2,并开始执行2的逻辑" << endl;
            break;
        case 3:
            cout << "接收到了信号id 3,并开始执行3的逻辑" << endl;
            break;
        case 4:
            cout << "接收到了信号id 4,并开始执行4的逻辑" << endl;
            break;
        }
    }
};
class Sender{
    //定义一个容器来保存信号id与所有感兴趣的接收者
    map<int,list<Recvbase*>> senderMap;
public:
    //信号添加到容器
    void addSenderMap(int msgid,Recvbase* recv){
        senderMap[msgid].push_back(recv);
    }
    //定义用于发出的信号函数
    void signal(int msgid){
        auto it = senderMap.find(msgid);
        if(it !=senderMap.end()){
            for(Recvbase* recv : it->second){
                recv->solt_function(msgid);
            }
        }
    }
};
int main()
{
    Sender sender;
    Recvbase* r1 = new Recv;
    Recvbase* r2 = new Recv;
    Recvbase* r3 = new Recv;
    Recvbase* r4 = new Recv;

    sender.addSenderMap(1,r1);
    sender.addSenderMap(2,r2);
    sender.addSenderMap(3,r3);
    sender.addSenderMap(4,r4);
    int msgid =0;
    for(;;){
        cin>>msgid;
        if(-1==msgid){
            cout<<"正在退出..."<<endl;
            break;
        }
        sender.signal(msgid);
    }
    return 0;
}

5.执行结果

也是Qt中信号与槽的基础实现
在这里插入图片描述

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值