设计模式——监听者观察者模式

监听器模式:事件源经过事件的封装传给监听器,当事件源触发事件后,监听器接收到事件对象可以回调事件的方法

观察者模式:观察者(Observer)相当于事件监听者,被观察者(Observable)相当于事件源和事件,执行逻辑时通知observer即可触发oberver的update,同时可传被观察者和参数

观察者模式有时被称作发布/订阅模式,观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。

感知事件的发生只由一个类对象负责,即观察者

对于事件的处理由监听者处理

1.监听者必须要告诉观察者自己关注的事件

2.当消息发生以后通过什么东西告诉监听者事件发生了

so,监听者一般会向观察者注册回调函数,当事件发生后观察者会通过回调函数告诉监听者事件发生了

eg:

#include<iostream>
#include<string>
#include<vector>
#include<map>
#include<functional> //函数对象的库
#include<iterator>  //迭代器
#include<algorithm> //泛型算法
using namespace std;

class Listener
{
public:
	Listener(string name):_name(name){}
	virtual void handleMessage(int msg)=0;
protected:
	string _name;
};

class Listener1:public Listener
{
public:
	Listener1(string name):Listener(name){}
	virtual void handleMessage(int msg)
	{
		cout<<_name<<" recv";
		switch(msg)
		{
		case 0:
			cout<<" 0 meg"<<endl;
			break;
		case 1:
			cout<<" 1 meg"<<endl;
			break;
		case 2:
			cout<<" 2 meg"<<endl;
			break;
		default:
			break;
		}
	}

};



class Listener2:public Listener
{
public:
	Listener2(string name):Listener(name){}
	virtual void handleMessage(int msg)
	{
		cout<<_name<<" recv";
		switch(msg)
		{
		case 0:
			cout<<" 0 meg"<<endl;
			break;
		case 2:
			cout<<" 2 meg"<<endl;
			break;
		default:
			break;
		}
	}

};



class Listener3:public Listener
{
public:
	Listener3(string name):Listener(name){}
	virtual void handleMessage(int msg)
	{
		cout<<_name<<" recv";
		switch(msg)
		{
		case 0:
			cout<<" 0 meg"<<endl;
			break;
		case 1:
			cout<<"1 meg"<<endl;
			break;
		default:
			break;
		}
	}
};

class Observer
{
public:
	void Register(int msgid,Listener *listener)
	{
		map<int,vector<Listener*>>::iterator it=_observerMap.find(msgid);
		if(it==_observerMap.end())
		{
			vector<Listener*> tmpvec;
			tmpvec.push_back(listener);
			_observerMap[msgid]=tmpvec;
		}
		else
			it->second.push_back(listener);
	}

	void Dispatch(int msgid)
	{
		map<int,vector<Listener*>>::iterator it=_observerMap.find(msgid);
		if(it==_observerMap.end())
		return;

		vector<Listener*>::iterator vit=it->second.begin();
		for(;vit!=it->second.end();vit++)
		{
			(*vit)->handleMessage(msgid);
		}
	}
private:
	map<int,vector<Listener*>> _observerMap;
};
int main()
{
	Observer obser;
	Listener *p1=new Listener1("listener1");
	Listener *p2=new Listener2("listener2");
	Listener *p3=new Listener3("listener3");

	obser.Register(0,p1);
	obser.Register(1,p1);
	obser.Register(2,p1);
	obser.Register(0,p2);
	obser.Register(2,p2);
	obser.Register(0,p3);
	obser.Register(1,p3);

	int msgid;
	while(true)
	{
		cout<<"input msgid:";
		cin>>msgid;
		if(msgid==-1)
			break;
		obser.Dispatch(msgid);
	}
	return 0;
}

运行结果:

but,上面的监听者观察者模式不是线程安全的,因为,对象定义在线程1中,而观察者的handleMessage方法是在线程2中执行的,但是,此时你根本就不知道该对象是否还存在,调用会失败

线程安全的监听者观察者模式:

#include<iostream>
#include<string>
#include<vector>
#include<map>
#include<functional> //函数对象的库
#include<iterator>  //迭代器
#include<algorithm> //泛型算法
#include<memory>  //boost智能指针
using namespace std;

class Listener
{
public:
	Listener(string name):_name(name){}
	virtual void handleMessage(int msg)=0;
protected:
	string _name;
};

class Listener1:public Listener
{
public:
	Listener1(string name):Listener(name){}
	virtual void handleMessage(int msg)
	{
		cout<<_name<<" recv";
		switch(msg)
		{
		case 0:
			cout<<" 0 meg"<<endl;
			break;
		case 1:
			cout<<" 1 meg"<<endl;
			break;
		case 2:
			cout<<" 2 meg"<<endl;
			break;
		default:
			break;
		}
	}

};



class Listener2:public Listener
{
public:
	Listener2(string name):Listener(name){}
	virtual void handleMessage(int msg)
	{
		cout<<_name<<" recv";
		switch(msg)
		{
		case 0:
			cout<<" 0 meg"<<endl;
			break;
		case 2:
			cout<<" 2 meg"<<endl;
			break;
		default:
			break;
		}
	}

};



class Listener3:public Listener
{
public:
	Listener3(string name):Listener(name){}
	virtual void handleMessage(int msg)
	{
		cout<<_name<<" recv";
		switch(msg)
		{
		case 0:
			cout<<" 0 meg"<<endl;
			break;
		case 1:
			cout<<"1 meg"<<endl;
			break;
		default:
			break;
		}
	}
};

class Observer
{
public:
	void Register(int msgid,weak_ptr<Listener>listener)
	{
		map<int,vector<weak_ptr<Listener>>>::iterator it=_observerMap.find(msgid);
		if(it==_observerMap.end())
		{
			vector<weak_ptr<Listener>> tmpvec;
			tmpvec.push_back(listener);
			_observerMap[msgid]=tmpvec;
		}
		else
			it->second.push_back(listener);
	}

	void Dispatch(int msgid)
	{
		map<int,vector<weak_ptr<Listener>>>::iterator it=_observerMap.find(msgid);
		if(it==_observerMap.end())
		return;

		vector<weak_ptr<Listener>>::iterator vit=it->second.begin();
		for(;vit!=it->second.end();vit++)
		{
			//(*vit)->handleMessage(msgid);
			//在该线程中想要使用若指针
			//将弱指针提升为强智能指针,成功表示该对象还活着,失败返回空
			shared_ptr<Listener> p=(*vit).lock();
			if(p!=NULL)
			{
				p->handleMessage(msgid); 
			}
		}
	}
private:
	map<int,vector<weak_ptr<Listener>>> _observerMap;
};
int main()
{
	//监听者的线程代码1  
	//定义:shared_ptr,
	//强智能指针引用对象,对象不会析构,只有强智能指针出了作用域,引起智能指针的析构,
        //智能指针给该对象的引用计数减一,这个对象才析构
	//在产生对象的线程中,要把共享对象(强智能指针)传给(泄漏)其他线程要用弱指针
	//一个对象被强智能指针引用,该对象是不会析构的,弱指针只是观察对象,他可以观察对象是存活还是死亡的
	Observer obser;
	shared_ptr<Listener> p1(new Listener1("listener1"));
	shared_ptr<Listener> p2(new Listener2("listener2"));
	shared_ptr<Listener> p3(new Listener3("listener3"));

	obser.Register(0,p1);
	obser.Register(1,p1);
	obser.Register(2,p1);
	obser.Register(0,p2);
	obser.Register(2,p2);
	obser.Register(0,p3);
	obser.Register(1,p3);

	//观察者线程2
	int msgid;
	while(true)
	{
		cout<<"input msgid:";
		cin>>msgid;
		if(msgid==-1)
			break;
		obser.Dispatch(msgid);
	}
	return 0;
}

强弱智能指针解决c++共享对象的线程安全问题:

在定义智能指针对象的地方用强智能指针(强智能指针会对该对象的引用计数加一,强智能指针只要引用对象,对象是不会析构的,只有强智能指针有出了作用域,引起智能指针的析构,才会使该对象的引用计数减一,这个对象才析构),要把共享对象(强智能指针对象)泄漏给其他线程用弱智智能指针(强智能指针只要引用对象,对象是不会析构的,弱指针只是观察对象,他可以观察该对象是存活的还是死亡的),想要在其他线程中使用该对象要先把若智能指针转成强智能指针,用lock(),提升成功表示该对象还活着,提升失败返回空

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值