观察者模式

观察者模式

又称发布-订阅模式,很容易和生产者-消费者模式搞混,生产者和消费者是操作系统线程模型中,描述线程通信方式,和设计模式是两码事。

角色一:观察者 角色二:监听者

监听者(1) 监听者(2) 监听者(3) 监听者(4) 监听者(5) 监听者(6)

​ 观察者:观察事件的发生

​ event1 : 监听者(2) 监听者(4)

​ event2 : 监听者(4) 监听者(6)

观察者设计:

1.可以接受监听者注册的事件

2.当事件发生后,能够通知响应的监听者处理它所感兴趣的事件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#include <iostream>
#include <string>
#include <unordered_map>
#include <list>
using namespace std;

//监听者的基类类型
class Listen{
public:
Listen(string name):_name(name){}
virtual void handlemessage(int eventid)=0;
protected:
string _name;
};
class Listen1:public Listen{
public:
Listen1(string name):Listen(name){};
void handlemessage(int eventid){
cout<<_name<<" handle messsage";
switch(eventid){
case 1:
cout<<"1"<<endl;
break;
case 2:
cout<<"2"<<endl;
break;
}
}
};
//一个具体的监听者
class Listen2:public Listen{
public:
Listen2(string name):Listen(name){};
void handlemessage(int eventid){
cout<<_name<<" handle messsage";
switch(eventid){
case 2:
cout<<"2"<<endl;
break;
case 3:
cout<<"3"<<endl;
break;
}
}
};
class Listen3:public Listen{
public:
Listen3(string name):Listen(name){};
void handlemessage(int eventid){
cout<<_name<<" handle messsage";
switch(eventid){
case 1:
cout<<"1"<<endl;
break;
case 3:
cout<<"3"<<endl;
break;
}
}
};
//定义观察者类型
class Observer{
public:
//注册监听者感兴趣的事件,
void registevent(Listen *listener,int eventid){
_eventmap[eventid].push_back(listener);
}
//删除监听者感兴趣的事件
void removeevent(Listen *listener,int eventid){
auto it=_eventmap.find(eventid);
if(it!=_eventmap.end()){
auto &mylist=it->second;
for(auto it1=mylist.begin();it1!=mylist.end();++it1){
if(*it1==listener){
mylist.erase(it1);
return ;
}
}
}
}
//eventid事件发生,通知响应的监听者处理事件
void notifyevent(int eventid){
auto it=_eventmap.find(eventid);
if(it!=_eventmap.end()){
auto &mylist =it->second;
for(auto *p:mylist){
//通过监听者的指针,调用其处理事件的方法
p->handlemessage(eventid);
}
}
}
private:
//定义成员变量,保存监听者以及它所感兴趣的事件
unordered_map<int,list<Listen*>>_eventmap;
};
int main()
{
Listen *p1=new Listen1("张伟");
Listen *p2=new Listen2("大力");
Listen *p3=new Listen3("赵海棠");

Observer obser;
obser.registevent(p1,1);
obser.registevent(p1,2);
obser.registevent(p2,2);
obser.registevent(p2,3);
obser.registevent(p3,1);
obser.registevent(p3,3);
int eventid;
for(;;)
{
cout<<"eventid :";
cin>>eventid;
obser.notifyevent(eventid);
obser.removeevent(p3,3);
}

return 0;
}

测试,首先3事件赵海棠可以接收到,但是运行一次之后,赵海棠被注销了,所以接受不到。