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出来的,即需在堆上创建的。
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 #endif4、测试示例
void Test() { IPursuit* poIXiaoMing = new CPursuit(_T("XiaoMing")); CProxy oCProxy; oCProxy.SetPursuit(poIXiaoMing); oCProxy.SendFlowers(); }5、代理类的应用
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://blog.csdn.net/gufeng99
原文地址:http://blog.csdn.net/gufeng99/article/details/46659157