设计模式_行为型模式_观察者模式
2023-12-15 11:22:00
行为型模式:主要关注的是对象之间的通信
例如:一个对象调用另一个对象的成员 方法
目的:
观察者-监听者模式(发布-订阅模式)设计模式:主要关注的是对象的一对多的关系,也就是多个对象都依赖一个对象,当该对象的状态发生改变时,其它对象都能够接收到相应的通知。
应用场景:
例如一组数据(数据对象)就是一个对象,通过这一组数据可以生成曲线图(对象1),柱状图(对象2),圆饼图(对象3)。这些图像只是样子不一样,但是都基于同一个数据对象的改变而发生的变化。因此当数据对象的数据发生改变,其他三个对象就需要及时收到通知发生相应的响应
代码实现
#include<iostream>
#include<mutex>
#include<memory>
#include<unordered_map>
#include<list>
using namespace std;
//观察者抽象类
class Observer
{
public:
//处理消息的接口
virtual void handle(int msgid) = 0;
};
//第一个观察者实例
class Observer1:public Observer
{
public:
//处理消息的接口
void handle(int msgid)
{
switch (msgid)
{
case 1:
cout << "Observer1 recv 1 msg" << endl;
break;
case 2:
cout << "Observer1 recv 2 msg" << endl;
break;
default:
cout << "Observer1 recv unknow msg" << endl;
break;
}
}
};
class Observer2 :public Observer
{
public:
//处理消息的接口
void handle(int msgid)
{
switch (msgid)
{
case 2:
cout << "Observer2 recv 2 msg" << endl;
break;
default:
cout << "Observer2 recv unknow msg" << endl;
break;
}
}
};
class Observer3 :public Observer
{
public:
//处理消息的接口
void handle(int msgid)
{
switch (msgid)
{
case 1:
cout << "Observer3 recv 1 msg" << endl;
break;
case 3:
cout << "Observer3 recv 3 msg" << endl;
break;
default:
cout << "Observer3 recv unknow msg" << endl;
break;
}
}
};
class Subject//需要存储每一个观察者感兴趣的事件
{
public:
void addObserver(Observer*obser,int msgid)
{
//subMap[msgid].push_back(obser);
auto it = subMap.find(msgid);
if (it != subMap.end())
{
it->second.push_back(obser);
}
else
{
list<Observer*>lis;
lis.push_back(obser);
subMap.insert({ msgid,lis });
}
}
//主题检测发生改变,通知相应的观察者对象处理事件
void dispath(int msgid)
{
auto it = subMap.find(msgid);
if (it != subMap.end())
{
for (Observer* pobser : it->second)
{
pobser->handle(msgid);
}
}
}
private:
//因为对一个消息感兴趣的可能是多个观察者所以使用list存储观察者
unordered_map<int, list<Observer*>>subMap;
};
int main()
{
Subject sub;
Observer* p1 = new Observer1();
Observer* p2 = new Observer2();
Observer* p3 = new Observer3();
sub.addObserver(p1, 1);
sub.addObserver(p1, 2);
sub.addObserver(p2, 2);
sub.addObserver(p3, 1);
sub.addObserver(p3, 3);
int msgid = 0;
for (;;)
{
cout << "请输入消息id: " << endl;
cin >> msgid;
if (msgid == -1)
{
break;
}
sub.dispath(msgid);
}
return 0;
}
文章来源:https://blog.csdn.net/qq_48083892/article/details/135010139
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!