一、引言
观察者设计模式:用来解决两个不相关对象之间的一对一或一对多的通信模型。是一种编程套路。
二、什么是观察者设计模式?
(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;
}
运行结果: