博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
大话设计模式C++版——代理模式
阅读量:6307 次
发布时间:2019-06-22

本文共 3406 字,大约阅读时间需要 11 分钟。

    本篇開始前先发个福利。程杰的《大话设计模式》一书高清电子版(带文件夹)已上传至CSDN,免积分下载。

下载地址:
    代理模式是一种比較简单但却有用的设计模式,他能够灵活的更换代理的对象。但保证功能的完整性。就如卖衣服的代理商。他能够代理美特斯邦威的衣服,假设美特斯邦威的衣服被大家吐槽不好卖了,他还能够换去代理卖佐丹奴的,但无论怎么更换,还是能满足大家的需求——买衣服。

    以下以大话设计模式书中的样例为例,设计一个代理帮小明送花给小红。

1、根据接口编程。设计代理对象的接口

class IPursuit{public:	virtual	~IPursuit()	{}	virtual	void	SendFlowers() = 0;};
2、代理类,也继承代理对象类,保持接口一致
class CProxy : public IPursuit{public:	CProxy() : m_poIPursuit(NULL)	{}	~CProxy()	{		if (m_poIPursuit)		{			delete	m_poIPursuit;			m_poIPursuit = NULL;		}	}		void	SetPursuit(IPursuit* poIPursuit)	{		//假设有旧的代理,要先删除。否则会造成内存泄漏		if (m_poIPursuit)		{			delete	m_poIPursuit;		}		m_poIPursuit = poIPursuit;	}	void	SendFlowers()	{		if (m_poIPursuit)		{			printf("Proxy help ");			m_poIPursuit->SendFlowers();		}	}private:	IPursuit*	m_poIPursuit;};
    代理类实际上啥也没干,仅仅是对相同的函数调用了一手被代理的对象的相应函数,当了一回二传手的角色。这里要注意代理对象因为会在代理中被释放,所以代理的对象一律必须是new出来的。即需在堆上创建的。
3、被代理对象类
class CPursuit : public IPursuit{public:	CPursuit(TString tstrName) : m_tstrName(tstrName) {}	~CPursuit()	{}	void	SendFlowers()	{		_tprintf(_T("%s sent flowers to Xiaohong\n"), m_tstrName.c_str());	}private:	TString	m_tstrName;};
另附上TString宏
#ifdef  UNICODE	#define	TString	std::wstring#else	#define	TString	std::string#endif
4、測试演示样例
void	Test(){	IPursuit*	poIXiaoMing = new CPursuit(_T("XiaoMing"));	CProxy		oCProxy;		oCProxy.SetPursuit(poIXiaoMing);	oCProxy.SendFlowers();}
5、代理类的应用
    这个样例非常形象,但却非常难看出代理模式的应用和长处。实际上在《 》中有一个操作数据库管理员工信息的样例,因为可能会在使用数据库的过程中切换数据库。如曾经用的MySql,可能某个客户要求支持Access,这时就得进行切换了。此时用代理模式一样能够实现。
5.1 代理模式实现员工数据库管理类对数据库的切换
typedef	struct Employee {	int		nID;	TString	tstrName;};class IEmployee{public:	~IEmployee()	{}		virtual	bool		InserttoDB(Employee& stEmployee) = 0;	virtual	Employee	GetEmployee(int nID) = 0;};class CProxy : public IEmployee{public:public:	CProxy() : m_poIEmployee(NULL)	{}	~CProxy()	{		if (m_poIEmployee)		{			delete	m_poIEmployee;			m_poIEmployee = NULL;		}	}		void		SetEmployee(IEmployee* poIEmployee)	{		if (m_poIEmployee)		{			delete	m_poIEmployee;		}		m_poIEmployee = poIEmployee;	}	bool		InserttoDB(Employee& stEmployee)	{		if (m_poIEmployee)		{			return	m_poIEmployee->InserttoDB(stEmployee);		}				return	false;	}	Employee	GetEmployee(int nID)	{		if (m_poIEmployee)		{			return	m_poIEmployee->GetEmployee(nID);		}				Employee	stEmployee;		return	stEmployee;	}private:	IEmployee*	m_poIEmployee;};class CEmployeefromMysql : public IEmployee{public:	bool		InserttoDB(Employee& stEmployee)	{		_tprintf(_T("Insert employee %s into mysql\n"), stEmployee.tstrName.c_str());		return	true;	}		Employee	GetEmployee(int nID)	{		Employee	stEmployee;		printf("Get an employee from mysql by id %d\n", nID);		return	stEmployee;	}};class CEmployeefromAccess : public	IEmployee{public:	bool		InserttoDB(Employee& stEmployee)	{		_tprintf(_T("Insert employee %s into access\n"), stEmployee.tstrName.c_str());		return	true;	}		Employee	GetEmployee(int nID)	{		Employee	stEmployee;		printf("Get an employee from access by id %d\n", nID);		return	stEmployee;	}};
5.2 使用演示样例
void	DataBaseTest(){	IEmployee*	poIEmployee = new CEmployeefromMysql();	CProxy		oCProxy;	oCProxy.SetEmployee(poIEmployee);		Employee	stEmployee;	stEmployee.nID = 1;	stEmployee.tstrName = _T("Jim");		oCProxy.InserttoDB(stEmployee);		//切换数据库对象	poIEmployee	= new	CEmployeefromAccess();		oCProxy.SetEmployee(poIEmployee);	oCProxy.InserttoDB(stEmployee);}
    从使用演示样例中就能够看出,代理类支持客户使用过程中动态切换数据库,这是和工厂模式最大的一点不同。特别适用于在常常须要切换类似对象模式的地方。

转载地址:http://qenxa.baihongyu.com/

你可能感兴趣的文章
Visual Studio 15.4发布,新增多平台支持
查看>>
有赞透明多级缓存解决方案(TMC)设计思路
查看>>
如何设计高扩展的在线网页制作平台
查看>>
Git 2.5增加了工作树、改进了三角工作流、性能等诸多方面
查看>>
Swift 5将强制执行内存独占访问
查看>>
中台之上(二):为什么业务架构存在20多年,技术人员还觉得它有点虚?
查看>>
深度揭秘腾讯云低功耗广域物联网LPWAN 技术及应用
查看>>
与Jeff Sutherland谈敏捷领导力
查看>>
More than React(四)HTML也可以静态编译?
查看>>
React Native最佳学习模版- F8 App开源了
查看>>
云服务正在吞噬世界!
查看>>
阅读Android源码的一些姿势
查看>>
Web语义化标准解读
查看>>
一份代码构建移动、桌面、Web全平台应用
查看>>
高性能 Lua 技巧(译)
查看>>
区分指针、变量名、指针所指向的内存
查看>>
异步编程的世界
查看>>
最近话题火爆的四件事你知道不?
查看>>
SpringBoot整合MyBatis
查看>>
云计算产业如何率先推行信用管理?
查看>>