【c++】设计模式——观察者模式

三、Observe模式(观察者模式)

Observe模式分为观察者和监听者两种角色。

观察者:观察事件;并且通知对于该事件感兴趣的监听者;(也就是两件事,一是注册事件、regsitermessage;二是发布事件,handlemessage);

监听者:处理事件;

Observe的一个实例model/view/control(MVC)在系统开发架构设计中有着很重要的地位和意义,MVC实现了业务逻辑和表示层的解耦。当然MVC只是观察者模式的一个实例。观察者模式要解决的问题是:建立一个一(subject)对多(observe)的依赖关系,并且做到当“一”变化的时候,依赖这和“一”的多也能够同时改变。

Observer模式的结构图:

【c++】设计模式——观察者模式

目标的subject依赖于它的观察者的注册(attach)和注销(detach)操作,并且提供了使得依赖与它的所有观察者同步的操作(notify)。观察者Observer则提供了一个update操作,注意这里的observer的update操作并不在observer改变了subject目标状态的时候就对自己进行更新,这个更新操作要延迟到subject对象发出notify通知所有observer进行修改。

观察者模式的使用场景:

    1、当一个抽象模型有两个方面,其中一个方面依赖于另一个方面。可将这二者封装在独立的对象中以使它们可以各自独立的改变个复用;

    2、当一个对象的改变需要同时改变其它对象,而不知道具体有多少对象有待改变;

    3、当一个对象必须通知其他对象,而它又不能假定其它对象是谁,即这些对像都是松耦合的。

观察者的简单实现:

class Listener
{
public:
	Listener(std::string name) :mname(name){}
	virtual void handleMessage(int message)const = 0;//处理事件
protected:
	std::string mname;
};
class Listener1:public Listener
{
public:
	Listener1(std::string name) :Listener(name){}
	virtual void handleMessage(int message)const
	{
		switch (message)
		{
		case 1:
			std::cout << mname << " has been solved 1 message!" << std::endl;
			break;
		case 2:
			std::cout << mname << " has been solved 2 message!" << std::endl;
			break;
		default:
			std::cout << mname << " no interested this message!" << std::endl;
			break;
		}
	}
};
class Listener2:public Listener
{
public:
	Listener2(std::string name) :Listener(name){}
	virtual void handleMessage(int message)const
	{
		switch (message)
		{
		case 2:
			std::cout << mname << " has been solved 2 message!" << std::endl;
			break;
		case 3:
			std::cout << mname << " has been solved 3 message!" << std::endl;
			break;
		default:
			std::cout << mname << " no interested this message!" << std::endl;
			break;
		}
	}
};
class Listener3:public Listener
{
public:
	Listener3(std::string name) :Listener(name){}
	virtual void handleMessage(int message)const
	{
		switch (message)
		{
		case 1:
			std::cout << mname << " has been solved 1 message!" << std::endl;
			break;
		case 3:
			std::cout << mname << " has been solved 3 message!" << std::endl;
			break;
		default:
			std::cout << mname << " no interested this message!" << std::endl;
			break;
		}
	}
};

class Observe//观察者
{
public:
	typedef std::map<int, std::vector<const Listener*>> _Mty;
	typedef std::vector<const Listener*> _Vty;
	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++;
			}
		}
	}
	void registerMessage(int message, const Listener* pls)//注册事件
	{
		_Mty::iterator fit = mymap.find(message);
		if (fit != mymap.end())
		{
			fit->second.push_back(pls);
		}
		else
		{
			_Vty vec;
			vec.push_back(pls);
			mymap[message] = vec;
		}
	}
private:
	map<int, std::vector<const Listener*>> mymap;
};

上述代码中的Observe就是我们的观察者用来观察事件,当有事件到来的时候,观察者将事件下发给对该事件感兴趣的监听者,监听者对这一事件进行处理。

 

观察者的优点:

目标和观察者之间完全解耦,不需要特定接口,可以各自扩展;

可以很方便的是实现跨进程、线程的观察者。这得益于标准的消息机制;

缺点:性能方面的时间延迟的问题;对于某一个具体subject的状态改变,所有具体observer必须逐步update(),即业务逻辑处理,如果observe集合过大,那么就存在遍历性能的问题

上一篇:有关StandardScaler的transform和fit_transform方法


下一篇:05_机器学习开发流程