代理模式(Proxy)
关于代理,ITer做常见的应该就是用来翻鸡爱抚大不留的代理了。
生活中也有很多代理,比如在北京不收中介费的在租房中介,这帮人就叫代理,链家这样的房产中介也叫代理,只不过是收中介费的代理。
恰好今天中午在公司楼道里吃午饭(热干面,楼下超市买的),刚吃了几口,进来一个抽烟的哥们,进来跟我打招呼,应该是隔壁公司的,隔壁公司是家律所,他说他不是律师,是做专利的,也就是代理专利,一般介于客户和知识产权局和专利局之间,所以,他就是一个代理。
用下图来说明
代理模式的示意图如下
Subject是一些需要做的工作,只有一些接口,以专利来说,可以有:【提交申请】【提交材料】【交费】等;
RealSubject是真正去做事的人,RealSubject实现了Subject的接口
Proxy是代理,Proxy也实现了Subject的接口,其在这些接口的内部去调用RealSubject实现的相应接口。
代理模式隐藏了真正干活的人RealSubject, 由于提供给客户的是Proxy,所以RealSubject和Proxy应该是相关的。
下面以客户请专利公司代为申请专利为例子来描述,如下
申请专利需要的【申请专利】抽象类,接口
/************************************************************************ 设计模式4 代理模式 代理模式,即客户和代理打交道,而代理又在内部调动相应的真正干活的人去干活 对客户来说,真正干活的人是透明的,他只和代理打交道。 以客户通过专利代理公司申请专利为例子来描述代理模式 ************************************************************************/
//【申请专利】接口,声明了一组申请专利的操作
class IApplyZL { public: IApplyZL(); virtual ~IApplyZL(); virtual void CommitApply() = 0; //提交申请
virtual void CommitFiles() = 0; //提交资料
virtual void Pay() = 0; //支付费用
}; IApplyZL::IApplyZL(){} IApplyZL::~IApplyZL(){} void IApplyZL::CommitApply() {} void IApplyZL::CommitFiles() {} void IApplyZL::Pay() {}
真正干活的【代理人/员工】类,员工类继承自IApplyZL抽象基类,实现了所有虚函数,表示员工可以干这个活
//【代理人】类,真正干活的人,他实现(有这样的能力)了申请专利要做的一些工作
class Worker : public IApplyZL { public: Worker(string strClient); virtual ~Worker(); virtual void CommitApply(); virtual void CommitFiles(); virtual void Pay(); protected: string m_strClient; //客户名
}; Worker::Worker(string strClient) : m_strClient(strClient){} Worker::~Worker(){} void Worker::CommitApply() { cout << "\r\n我正在为 "<<m_strClient<<" 先生/女士 提交专利申请!\r\n"; } void Worker::CommitFiles() { cout << "\r\n我正在为 "<<m_strClient<<" 先生/女士 提交专利申请需要的材料!\r\n"; } void Worker::Pay() { cout << "\r\n我正在为 "<<m_strClient<<" 先生/女士 提交专利申请需要需要的费用!\r\n"; }
面向客户的【代理公司】类,他也继承自IApplyZL抽象基类,实现了所有虚函数,表示可以承接这样的业务
//【代理公司】类,客户跟代理公司打交道,代理公司实现了IApplyZL的接口, //表示代理公司可以承接这样的业务
class ProxyZL : public IApplyZL { public: ProxyZL(string strClient); virtual ~ProxyZL(); virtual void CommitApply(); virtual void CommitFiles(); virtual void Pay(); protected: Worker* m_pWorker; //干活的员工
string m_strClient; //客户名
}; ProxyZL::ProxyZL(string strClient) : m_strClient(strClient), m_pWorker(NULL) {} ProxyZL::~ProxyZL(){} void ProxyZL::CommitApply() { if(NULL == m_pWorker) m_pWorker = new Worker(m_strClient); m_pWorker->CommitApply(); } void ProxyZL::CommitFiles() { if(NULL == m_pWorker) m_pWorker = new Worker(m_strClient); m_pWorker->CommitFiles(); } void ProxyZL::Pay() { if(NULL == m_pWorker) m_pWorker = new Worker(m_strClient); m_pWorker->Pay(); }
main函数以及执行情况
int _tmain(int argc, _TCHAR* argv[]) { ProxyZL proxy("cuish"); proxy.CommitApply(); proxy.CommitFiles(); proxy.Pay(); cout<<endl<<endl; return 0; }
PS:
想到一个问题,总是感觉代理模式和简单工厂模式,策略模式很相似,可是相似在什么地方又不好说。假如在【ProxyZL】类中的成员Worker *m_pWorker改为某个继承自IApplyZL抽象基类的子类的子类,如下:
即class Workers : public IApplyZL{};
ProxyZL类的成员改为Workers *m_pSomeWorker; //某个员工
又有Workers类的若干个子类,Workers类可以继续为抽象基类,在ProxyZL类中根据构造函数的参数不同可以用Workers类的不同子类的实例(new 子类())的指针给m_pSomeWorker指针赋值,再根据多态的性质,即可去调用不同的子类去执行申请专利的操作。 如果是这样,那就和简单工厂/策略模式很类似了。
如下:
//【员工】类,仍然为抽象基类,没有实现IApplyZL中的纯虚函数
class Workers : public IApplyZL { public: Workers(string strClient); virtual ~Workers(); protected: string m_strClient; //客户名
}; Workers::Workers(string strClient) : m_strClient(strClient){} Workers::~Workers(){}
两个员工类
//【代理人1】类,真正干活的人,他实现(有这样的能力)了申请专利要做的一些工作
class Worker1 : public Workers { public: Worker1(string strClient); virtual ~Worker1(); virtual void CommitApply(); virtual void CommitFiles(); virtual void Pay(); protected: const string m_strWorkerName; }; Worker1::Worker1(string strClient) : Workers(strClient), m_strWorkerName(string("worker1")){} Worker1::~Worker1(){} void Worker1::CommitApply() { cout << "\r\n"<<m_strWorkerName<<"正在为 "<<m_strClient<<" 先生/女士 提交专利申请!\r\n"; } void Worker1::CommitFiles() { cout << "\r\n"<<m_strWorkerName<<"正在为 "<<m_strClient<<" 先生/女士 提交专利申请需要的材料!\r\n"; } void Worker1::Pay() { cout << "\r\n"<<m_strWorkerName<<"正在为 "<<m_strClient<<" 先生/女士 提交专利申请需要需要的费用!\r\n"; } //
//【代理人2】类,真正干活的人,他实现(有这样的能力)了申请专利要做的一些工作
class Worker2 : public Workers { public: Worker2(string strClient); virtual ~Worker2(); virtual void CommitApply(); virtual void CommitFiles(); virtual void Pay(); protected: const string m_strWorkerName; //客户名
}; Worker2::Worker2(string strClient) : Workers(strClient), m_strWorkerName(string("worker2")){} Worker2::~Worker2(){} void Worker2::CommitApply() { cout << "\r\n"<<m_strWorkerName<<"正在为 "<<m_strClient<<" 先生/女士 提交专利申请!\r\n"; } void Worker2::CommitFiles() { cout << "\r\n"<<m_strWorkerName<<"我正在为 "<<m_strClient<<" 先生/女士 提交专利申请需要的材料!\r\n"; } void Worker2::Pay() { cout << "\r\n"<<m_strWorkerName<<"我正在为 "<<m_strClient<<" 先生/女士 提交专利申请需要需要的费用!\r\n"; }
代理公司类
//【代理公司】类,客户跟代理公司打交道,代理公司实现了IApplyZL的接口, //表示代理公司可以承接这样的业务
class ProxyZL : public IApplyZL { public: ProxyZL(string strClient); virtual ~ProxyZL(); virtual void CommitApply(); virtual void CommitFiles(); virtual void Pay(); protected: Workers* m_pSomeWorker; //某个干活的员工
string m_strClient; //客户名
}; ProxyZL::ProxyZL(string strClient) : m_strClient(strClient) { if (m_strClient == string("cuish")) { m_pSomeWorker = new Worker1(m_strClient); } else if(m_strClient == string("zhangsan")) { m_pSomeWorker = new Worker2(m_strClient); } else { m_pSomeWorker = NULL; } } ProxyZL::~ProxyZL() { if (NULL != m_pSomeWorker) delete m_pSomeWorker; } void ProxyZL::CommitApply() { if(NULL != m_pSomeWorker) m_pSomeWorker->CommitApply(); } void ProxyZL::CommitFiles() { if(NULL != m_pSomeWorker) m_pSomeWorker->CommitFiles(); } void ProxyZL::Pay() { if(NULL != m_pSomeWorker) m_pSomeWorker->Pay(); }
客户端和执行结果
int _tmain(int argc, _TCHAR* argv[]) { ProxyZL proxy("cuish"); proxy.CommitApply(); proxy.CommitFiles(); proxy.Pay(); cout<<endl<<endl; ProxyZL proxy2("zhangsan"); proxy2.CommitApply(); proxy2.CommitFiles(); proxy2.Pay(); cout<<endl<<endl; return 0; }
嗯,有点像简单工厂模式和代理模式的结合了。