代理模式
尽管Decorator的实现部分与代理相似,但Decorator的目的不一样。Decorator为对象添加一个或多个功能,而代理则控制对对象的访问。
意图:
为其他对象提供一种代理以控制对这个对象的访问。
适用性:
在需要用比较通用和复杂的对象指针代替简单的的指针的时候,使用代理模式。
1、远程代理,也就是为一个对象在不同的地址空间提供局部代表。这样可以隐藏一个对象存在于不同地址空间的事实。
2、虚拟代理,是根据需要创建开销很大的对象。通过它来存放实例化需要很长时间的真实对象。
3、安全代理,用来控制真实对象访问的权限。
4、智能指引,取代了简单的指针,它在访问对象时执行一些附加操作。
UML:
参与者:
Proxy
— 保存一个引用使得代理可以访问实体。若RealSubject和Subject的接口相同,proxy会引用Subject。
— 提供一个与Subject的接口相同的接口,这样代理就可以用来代替实体。
— 控制对实体的存取,并可能负责创建和删除它。
— 其它功能依赖于代理的类型。
Subject
— 定义RealSubject和Proxy的共用接口,这样就可以在任何使用RealSubject的地方都可以使用Proxy。
RealSubject
— 定义Proxy所代表的实体。
代码实现:
一、大话设计模式里面的例子:小王想追求小娟,但他不认识小娟。但他的朋友小林认识小娟,所以他通过让小林帮忙送礼物的方式追求小娟。
这里的小林就是我们的代理!
首先,我们实现一个女孩类:
class Girl{ public: Girl(char* name = ""):mName(name){} char* getName() { return mName; } private: char* mName; };
送礼物的接口:
class GiveGift { public: virtual void GiveDolls() = 0; virtual void GiveFlowers() = 0; virtual void GiveChocolate() = 0; };
送礼物实例类(小王)
class Puisuit : public GiveGift { public: Puisuit(Girl mm):mGirl(mm){} virtual void GiveDolls() { cout<<"送"<<mGirl.getName()<<"玩具!"<<endl; } virtual void GiveFlowers() { cout<<"送"<<mGirl.getName()<<"鲜花!"<<endl; } virtual void GiveChocolate() { cout<<"送"<<mGirl.getName()<<"巧克力!"<<endl; } private: Girl mGirl; };
送礼物代理类(小林)
class Proxy : public GiveGift { public: Proxy(Girl mm) { mPuisuit = new Puisuit(mm); } virtual void GiveDolls() { mPuisuit->GiveDolls(); } virtual void GiveFlowers() { mPuisuit->GiveFlowers(); } virtual void GiveChocolate() { mPuisuit->GiveChocolate(); } private: Puisuit* mPuisuit; };
客户端代码:
#include <iostream> #include "Proxy.h" using namespace std; int main() { Girl mm("小娟"); Proxy pro(mm); pro.GiveChocolate(); pro.GiveDolls(); pro.GiveFlowers(); return 0; }
二、游戏中,通过代理来控制不同vip玩家的游戏权限。
基本操作接口
class Play { public: virtual void Play1() = 0; virtual void Play2() = 0; virtual void Play3() = 0; };
操作类:
class Player:public Play { public: void Play1() { cout<<"战役"<<endl; } void Play2() { cout<<"军团"<<endl; } void Play3() { cout<<"神器"<<endl; } };
不同vip玩家的代理:
class ProxyPlayerVip0:Play { public: ProxyPlayerVip0() { mPlayer = new Player; } void Play1() { mPlayer->Play1(); } void Play2() { cout<<"没有权限"<<endl; } void Play3() { cout<<"没有权限"<<endl; } private: Play* mPlayer; }; class ProxyPlayerVip1:Play { public: ProxyPlayerVip1() { mPlayer = new Player; } void Play1() { mPlayer->Play1(); } void Play2() { mPlayer->Play2(); } void Play3() { cout<<"没有权限"<<endl; } private: Play* mPlayer; };
客户端代码:
ProxyPlayerVip0 pro5;
pro5.Play1();
pro5.Play2();
pro5.Play3();
ProxyPlayerVip1 pro1;
pro1.Play1();
pro1.Play2();
pro1.Play3();
结果:
战役
没有权限
没有权限
战役
军团
没有权限