C++:观察者设计模式

本文详细介绍了观察者设计模式,一种用于实现对象间一对多通信的编程模式。观察者模式定义了对象间的状态变化依赖关系,使得当被观察对象状态改变时,所有依赖它的对象都能得到通知并自动更新。在软件开发中,观察者模式广泛应用于界面交互、业务逻辑和权限管理等场景。通过示例代码展示了如何创建观察者和被观察者类,以及如何实现添加观察者、发送通知的功能。
摘要由CSDN通过智能技术生成

一、引言

观察者设计模式:用来解决两个不相关对象之间的一对一或一对多的通信模型。是一种编程套路。

二、什么是观察者设计模式?

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

(2) 在观察者模式中,主体是通知的发布者,它发出通知时并不需要知道谁是它的观察者,可以任意数目的观察者订阅并接收通知。

(3) 观察者模式不仅被广泛应用于软件界面元素之间的交互,在业务对象之间的交互、权限管理等方面也有广泛的应用。

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

三、观察者设计模式是用来解决什么问题?

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

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

四、观察者设计模式的简易编程套路是什么?

(1) 假定两个类,一个为观察者类,一个为被观察者类。

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

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

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

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

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

五、代码演示 

#include <iostream>
#include <map>
#include <list>
using namespace std;
class Base_Recv
{
public:
    //在基类之中设定的槽函数接口函数(纯虚函数)
    virtual void slot_function(int msgid) = 0;
    virtual ~Base_Recv() = default;
};

class Recv:public Base_Recv
{
public:
    //重写基类的纯虚函数
    void slot_function(int msgid) override
    {
        switch(msgid){
        case 1:
            cout<<"接收到信号1,并执行了信号1所要执行的逻辑"<< endl;
            break;
        case 2:
            cout <<"接收到信号2,并执行了信号2所要执行的逻辑"<< endl;
            break;
        case 3:
            cout <<"接收到信号3,并执行了信号3所要执行的逻辑"<< endl;
            break;
        }
    }
};

class Sender
{
private:
    //设定一个map容器来保存这种映射关系
    map<int,list<Base_Recv*>> SenderMap;
public:
    //把对某一信号感兴趣的接收者的对象放入在容器中
    void addSenderMap(int msgid,Base_Recv* recv)
    {
        SenderMap[msgid].push_back(recv);
    }
    //发出信号函数:
    void single(int msgid)
    {
        auto it = SenderMap.find(msgid);
        for(Base_Recv* pRecv : it->second)
        {
            pRecv->slot_function(msgid);
        }
    }
};

int main()
{
    Sender sender;
    Base_Recv* recv1 = new Recv;
    Base_Recv* recv2 = new Recv;
    Base_Recv* recv3 = new Recv;
    //把信号与槽函数执行的对象绑定,并放入到map容器之中。
    sender.addSenderMap(1,recv1);
    sender.addSenderMap(2,recv2);
    sender.addSenderMap(3,recv3);
    //模仿发出信号的id
    int msgid;
    for(;;)
    {
        cout<<"请输入要发出的信号的id:"<< endl;
        cin >> msgid;
        if(msgid == -1)
        {
            break;
        }
        sender.single(msgid);
    }
    return 0;
}

运行结果: 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值