代理模式
盡管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();
結果:
戰役
沒有權限
沒有權限
戰役
軍團
沒有權限