什么是观察者模式???
是对象与对象之间的一对多的关系,当一个对象的状态改变时,他所对应的所有对象都要受到消息。observer对象通常有一个map表,map就是一种键值的对应关系,为了编码简单,用int代替事件的发生,map的second采用数组,存放基类指针。
上代码!
//非线程安全的
#include <iostream>
#include <vector>
#include <string>
#include <map>
using namespace std;
class Listener
//监听者
{
public:
Listener(string name):_name(name){}
virtual void handlemessage(int sig){}
string _name;
};
class Listener1 :public Listener
//监听者的派生类
{
public:
Listener1(string name):Listener(name){}
void handlemessage(int sig)
{
switch(sig)
{
case 0:
cout<<"Listener1 recv sig 0"<<endl;break;
case 1:
cout<<"Listener1 recv sig 1"<<endl;break;
default:break;
}
}
};
class Listener2 :public Listener
{
public:
Listener2(string name):Listener(name){}
void handlemessage(int sig)
{
switch(sig)
{
case 1:
cout<<"Listener2 recv sig 1"<<endl;break;
case 3:
cout<<"Listener2 recv sig 3"<<endl;break;
default:break;
}
}
};
class Listener3 :public Listener
{
public:
Listener3(string name):Listener(name){}
void handlemessage(int sig)
{
switch(sig)
{
case 2:
cout<<"Listener3 recv sig 2"<<endl;break;
default:break;
}
}
};
class Observer
{
public:
void registemessage(Listener *lis,int sig)
//观察者的注册函数,在map以sig为键找,
{
map<int,vector<Listener*>>::iterator it =
ma.find(sig);
if(it== ma.end())
//若未找到,添加sig,初始化对应的监听者指针数组
{
vector<Listener*> vec;
vec.push_back(lis);
ma.insert(make_pair(sig,vec));
}
else
//若找到了,直接加入sig对应的监听者指针数组
{
it->second.push_back(lis);
}
}
void sendmessage(int sig)
//消息的发送函数
{
map<int,vector<Listener*>>::iterator it = ma.find(sig);
//拿sig和map里的键比对,找到就调用对应second中的监听者对象指针数组,遍历数组,解引用之后调用对应监听者的处理函数
if(it != ma.end())
{
vector<Listener*>::iterator it2 = it->second.begin();
for( ; it2 != it->second.end();++it2)
{
(*it2)->handlemessage(sig);
}
}
}
map<int,vector<Listener*>> ma;
};
int main()
{
Observer ob;
Listener *p1 = new Listener1("Listener1");
Listener *p2 = new Listener2("Listener2");
Listener *p3 = new Listener3("Listener3");
ob.registemessage(p1,0);
ob.registemessage(p1,1);
ob.registemessage(p2,1);
ob.registemessage(p2,3);
ob.registemessage(p3,2);
while(1)
{
int sig;
cout<<"sig = ";
cin>>sig;
//模拟事件发生
ob.sendmessage(sig);
}
return 0;
运行结果如下: