观察者模式
1.观察者
1)通知
2)注册 事件 ==> 监听者
2.监听者
处理事件
观察者模式(有时又被称为发布-订阅模式、模型-视图模式、源-收听者模式或从属者模式)是软件设计模式的一种。观察者模式(Observer Pattern),定义了对象间的一对多的依赖关系,让多个观察者对象同时监听某一个主题对象(被观察者)。当主题对象的状态发生更改时,会通知所有观察者,让它们能够自动更新。
解决的问题:当一个类的状态变化需要通知多个类,且被通知的类型要动态变化时,就可以使用观察者模式。
实现Observer 模式要解决的问题为:建立一个一(Subject)对多(Observer)的依赖关系(map),并且做到当“一”变化的时候,依赖这个“一”的多也能够同步改变。
简单demo如下:
#include<string>
class Listerner // 监听者类,负责处理事件
{
public:
Listerner(std::string name) :mname(name){}
virtual void handleMessage(int message)const = 0; //将处理事件函数设置为纯虚函数
protected:
std::string mname;
};
class Listerner1 : public Listerner
{
public:
Listerner1(std::string name) :Listerner(name){}
virtual void handleMessage(int message)const
{
switch (message)
{
case 1:
std::cout << mname << " has been solved message 1" << std::endl;
break;
case 2:
std::cout << mname << " has been solved message 2" << std::endl;
break;
default:
std::cout << mname << " no interested this message" << std::endl;
break;
}
}
};
class Listerner2 : public Listerner
{
public:
Listerner2(std::string name) :Listerner(name){}
virtual void handleMessage(int message)const
{
switch (message)
{
case 1:
std::cout << mname << " has been solved message 1" << std::endl;
break;
case 2:
std::cout << mname << " has been solved message 2" << std::endl;
break;
default:
std::cout << mname << " no interested this message" << std::endl;
break;
}
}
};
class Listerner3 : public Listerner
{
public:
Listerner3(std::string name) :Listerner(name){}
virtual void handleMessage(int message)const
{
switch (message)
{
case 1:
std::cout << mname << " has been solved message 1" << std::endl;
break;
case 2:
std::cout << mname << " has been solved message 2" << std::endl;
break;
default:
std::cout << mname << " no interested this message" << std::endl;
break;
}
}
};
#include<map>
#include<vector>
class Obeserve //观察者类,负责通知监听者处理事件,和注册事件
{
public:
typedef std::map<int, std::vector<const Listerner*>> Mty; //map集合:事件和所对应的监听者集合
typedef std::vector<const Listerner*> Vty; //监听者集合
void registerMessage(int message, const Listerner* pls) //注册事件
{
Mty::iterator fit = mymap.find(message);
if (fit != mymap.end())
{
fit->second.push_back(pls); //注意map容器访问成员方式
}
else
{
Vty vec;
vec.push_back(pls);
mymap[message] = vec;
}
}
void notify(int message)
{
Mty::iterator fit = mymap.find(message);
if (fit != mymap.end())
{
Vty::iterator it = fit->second.begin();
while (it != fit->second.end())
{
(*it)->handleMessage(message);
it++;
}
}
}
private:
std::map<int, std::vector<const Listerner*>> mymap;
};
/*
l1 1 2
l2 2 3
l3 1 3
*/
int main()
{
Listerner1 l1("listerner1");//初始化三个监听者
Listerner2 l2("listerner2");
Listerner3 l3("listerner3");
Obeserve ob;
ob.registerMessage(1, &l1); //一号监听者对1.2号事件感兴趣
ob.registerMessage(2, &l1);
ob.registerMessage(2, &l2);//二号监听者对2.3号事件感兴趣
ob.registerMessage(3, &l2);
ob.registerMessage(1, &l3);//三号监听者对1.3号事件感兴趣
ob.registerMessage(3, &l3);
ob.notify(2);// 2号事件到来
return 0;
}
运行结果如下:
这个大佬有案例分析:C++ 观察者模式
博主之前更的设计模式一:单例模式