C++设计模式:观察者模式(监听者模式)

C++设计模式:观察者模式(监听者模式)

所谓观察者监听者模式就是:当观察者观察到事件到来之后,通知对该事件感兴趣的监听者进行相应的操作

需要解决的问题:

  • 观察者需要做的事情?
    ①事件到来的时候,通知感兴趣的监听者
    ②事件到来之前,先把监听者和事件的关系进行注册
  • 如何通知对该事件感兴趣的监听者?
    调用该监听者的接口(函数)。
  • 如何处理监听者和事件之间的关系?
    可能存在一个监听者对多个事件感兴趣,所以这里我们用C++中STL的map映射容器(一对多)。
    key存放事件名称,value存放一个vector容器,vector容器存放对该事件感兴趣的监听者。

监听者类的设计:

class Listener{
public:
	Listener(string name) :mname(name){}
	virtual void DealMessage(int message) = 0;
protected:
	string mname;
};

这里将事件处理函数设计成纯虚函数的原因:每个监听者感兴趣的事件不同,做出的操作也不同。

  • 模拟一个监听者1类的设计
class Listener1 :public Listener
{
public:
	Listener1(string name) :Listener(name){}
	void DealMessage(int message)
	{
		switch (message)
		{
		case 1:   //对事件一感兴趣
			cout << mname << ": 1  message has been deal" << endl;
			break;
		case 2:    //对事件二感兴趣
			cout << mname << ": 2  message has been deal" << endl;
			break;
		default:  //这个cout其实可以去掉,因为观察者的类设计,不会通过监听者不感兴趣的事件而调监听者的函数接口。
			cout << mname << ": no interested this message" << endl;
			break;
		}
	}
};

观察者类的设计:

class Oberseve{
public:
	typedef map<int, vector<Listener*>> mmap; //为了方便定义迭代器而类型重定义
	void notify(int message)  //事件到来,通知监听者
	{
		mmap::iterator fit = mymap.find(message);//通过键值在map容器中搜索该事件是否在容器中注册
		if (fit != mymap.end()) //事件存在,通知对应的监听者做出反应(调用该监听者接口)
		{
			vector<Listener*>::iterator eit = fit->second.begin();
			while (eit != fit->second.end())
			{
				(*eit)->DealMessage(message);//调用监听者的函数接口
				eit++;
			}
		}
		else  //未注册过该事件
		{
			cout << "no Listener has insterested this meeage" << endl;
		}
	}
	void registerMessage(int message, Listener* pl)  //注册事件
	{
		/*
		1.事件未注册
		2.事件存在,增加监听者
		*/
		mmap::iterator fit = mymap.find(message);
		if (fit == mymap.end())//没有该事件(迭代器已经指向容器最后一个key的下一个位置)
		{
			vector<Listener*>ve;
			ve.push_back(pl);
			mymap[message] = ve;
		}
		else   //有该事件
		{
			fit->second.push_back(pl);
		}
	}
private:
	map<int, vector<Listener*>> mymap;
};

主函数的设计:

int main()
{
	Listener1 l1("listener1");
	Listener2 l2("listener2");
	Listener3 l3("listener3");

	Oberseve ob;
	ob.registerMessage(1, &l1);
	ob.registerMessage(2, &l1);
	ob.registerMessage(2, &l2);
	ob.registerMessage(3, &l2);
	ob.registerMessage(1, &l3);
	ob.registerMessage(3, &l3);
	ob.notify(1);
	ob.notify(4);
	

我其实定义了三个监听者和三个事件为了测试,所以如果需要完整运行,只要模拟监听者1的类的设计再设计两个监听者2,3就可以了。

你可能感兴趣的:(观察者(监听者)模式,c++,设计模式)