设计模式---接口隔离模式之代理模式(Proxy)
一:概念
代理模式(Proxy Pattern)就是为其他对象提供一种代理以控制对这个对象的访问。 比如: 智能指针 为别人做嫁衣
所谓代理,是指具有与代理元(被代理的对象)具有相同的接口的类,客户端必须通过代理与被代理的目标类交互,而代理一般在交互的过程中(交互前后),进行某些特别的处理。
二:动机
在面向对象系统中,有些对象由于某种原因(比如对象创建开销很大或者某些操作需要安全控制或者需要进程外访问等),直接访问会给使用者、或者系统结构带来很多的麻烦。
如何在不失去透明操作对象的同时来管理/控制这些对象特有的复杂性?增加一层间接层是软件开发中常见的解决方法。
三:模式定义
为其他对象提供一种代理以控制(隔离,使用接口)对这个对象的访问。
--《设计模式》Gof
四:类图(结构)
五:代码讲解
(一)原代码
class ISubject{ //接口 public: virtual void process(); }; class RealSubject: public ISubject{ //继承接口实现 public: virtual void process(){ //.... } }; class ClientApp{ ISubject* subject; public: ClientApp(){ subject=new RealSubject(); //这里是不合适的,可能由于性能原因,安全控制,系统分步等,压根无法获取到实例 } void DoTask(){ //... subject->process(); //.... } };
(二)代理版本
class ISubject{ public: virtual void process(); }; //Proxy的设计 class SubjectProxy: public ISubject{ public: virtual void process(){ //对RealSubject的一种间接访问,很多操作和方案 //.... } }; class ClientApp{ ISubject* subject; public: ClientApp(){ subject=new SubjectProxy(); } void DoTask(){ //... subject->process(); //.... } };
六:要点总结
(一)“增加一层间接层”是软件系统中对许多复杂问题的一种常见解决方案。在面向对象系统中,直接使用某些对象会带来很多问题,作为间接层的Proxy对象便是解决这一问题的常用手段。
(二)具体Proxy设计模式的实现方法、实现粒度都相差很大,有些可能对单个对象做细粒度的控制,如copy-on-write技术,有些可能对组建模块提供抽象代理层,在架构层次对对象做proxy
(三)proxy并不一定要求保持接口完整的一致性,只要能够实现间接控制,有时候损及一些透明性是可以接受的。
七:案例实现:理论实现
#include <iostream> #include <string> using namespace std; //定义接口 class Interface { public: virtual void Request(string pass="") = 0; virtual ~Interface(){} }; //真实类,但是由于安全控制无法直接访问 class RealClass :public Interface { public: virtual void Request(string pass) { if (strcmp(pass.c_str(),"123456")) { cout << "can't visit" << endl; } else { cout << "really request" << endl; } } };
//代理类,内部含有密码,可以通过安全控制 class ProxyClass :public Interface { private: RealClass* m_realclass; public: virtual void Request(string pass="") { m_realclass = new RealClass(); m_realclass->Request("123456"); delete m_realclass; } };
//客户端 class Client { private: Interface* interfS; //直接访问 Interface* interfP; //代理访问 public: Client() { interfP = new ProxyClass(); interfS = new RealClass(); } void VisitRealObjByProxy() { interfP->Request(); } void VisitRealObj() { interfS->Request(); } ~Client() { delete interfP; delete interfS; } };
void main() { Client *c = new Client(); c->VisitRealObjByProxy(); c->VisitRealObj(); system("pause"); return; }
八:案例实现:书籍代理
#include <iostream> #include <string> using namespace std; //定义接口 class Interface { public: virtual void SaleBook() = 0; virtual ~Interface(){} };
//实体店 class RealClass :public Interface { public: virtual void SaleBook() { cout << "store shopping" << endl; } };
//代理类 class ProxyTaoBao :public Interface { private: RealClass* m_realclass; void Double() { cout << "discount" << endl; } public: virtual void SaleBook() //代理类在传递真实数据前进行某些处理 { m_realclass = new RealClass(); Double(); m_realclass->SaleBook(); delete m_realclass; } };
void main() { ProxyTaoBao* ptb = new ProxyTaoBao(); ptb->SaleBook(); system("pause"); return; }