Proxy代理模式
作用:為其他對象提供一種代理以控制對這個對象的訪問。
代理的種類:
如果按照使用目的來划分,代理有以下幾種:
遠程(Remote)代理:為一個位於不同的地址空間的對象提供一個局域代表對象。這個不同的地址空間可以是在本機器中,也可是在另一台機器中。遠程代理又叫做大使(Ambassador)。 也就是為一個對象在不同的地址空間提供局部代表。這樣可以隱藏一個對象存在於不同地址空間的事實。
虛擬(Virtual)代理:根據需要創建一個資源消耗較大的對象,使得此對象只在需要時才會被真正創建。是根據需要創建開銷很大的對象。通過它來存放實例化需要很長時間的真實對象。
Copy-on-Write代理:虛擬代理的一種。把復制(克隆)拖延到只有在客戶端需要時,才真正采取行動。
保護(Protect or Access)代理:控制對一個對象的訪問,如果需要,可以給不同的用戶提供不同級別的使用權限。 用來控制真實對象訪問時的權限。一般用於對象應該有不同的訪問權限的時候。
Cache代理:為某一個目標操作的結果提供臨時的存儲空間,以便多個客戶端可以共享這些結果。 防火牆(Firewall)代理:保護目標,不讓惡意用戶接近。 同步化(Synchronization)代理:使幾個用戶能夠同時使用一個對象而沒有沖突。
智能引用(Smart Reference)代理:當一個對象被引用時,提供一些額外的操作,比如將對此對象調用的次數記錄下來等。 是指當調用真實的對象時,代理處理另外一些事。如計算真實對象的引用次數,這樣當該對象沒有引用時,可以自動釋放它;或當第一次引用一個持久對象時,將它裝入內存;或在訪問一個實際對象前,檢查是否已經鎖定它,以確保其他對象不能改變它。它們都是通過代理在訪問一個對象時附加一些內務處理。
在所有種類的代理模式中,虛擬(Virtual)代理、遠程(Remote)代理、智能引用代理(Smart Reference Proxy)和保護(Protect or Access)代理是最為常見的代理模式。
UML圖:
Subject:聲明了真實主題和代理主題的共同接口,這樣一來在任何使用真實主題的地方都可以使用代理主題。
Proxy:代理主題角色內部含有對真是主題的引用,從而可以在任何時候操作真實主題對象;代理主題角色提供一個與真實主題角色相同的接口,以便可以在任何時候都可以替代真實主體;控制真實主題的應用,負責在需要的時候創建真實主題對象(和刪除真實主題對象);代理角色通常在將客戶端調用傳遞給真實的主題之前或之后,都要執行某個操作,而不是單純的將調用傳遞給真實主題對象。
ConcreteSubject:定義了代理角色所代表的真實對象。
代碼如下:
Proxy.h
1 #ifndef _PROXY_H_ 2 #define _PROXY_H_ 3 4 // 定義了Proxy和ConcreteSubject的公有接口, 5 // 這樣就可以在任何需要使用到ConcreteSubject的地方都使用Proxy. 6 class Subject 7 { 8 public: 9 virtual ~Subject(); 10 virtual void Request()=0; 11 protected: 12 Subject(); 13 }; 14 15 class ConcreteSubject : public Subject 16 { 17 public: 18 ConcreteSubject(); 19 ~ConcreteSubject(); 20 virtual void Request(); 21 }; 22 23 //定義代理類 24 class Proxy : public Subject 25 { 26 public: 27 Proxy(); 28 ~Proxy(); 29 void DoSomething1(); 30 virtual void Request(); 31 void DoSomething2(); 32 private: 33 Subject* _subject; 34 }; 35 #endif
Proxy.cpp
1 #include "Proxy.h" 2 #include "iostream" 3 4 using namespace std; 5 6 Subject::Subject() 7 {} 8 9 Subject::~Subject() 10 {} 11 12 ConcreteSubject::ConcreteSubject() 13 {} 14 15 ConcreteSubject::~ConcreteSubject() 16 {} 17 18 void ConcreteSubject::Request() 19 { 20 cout << "ConcreteSubject::Request" << endl; 21 } 22 23 Proxy::Proxy() : _subject(NULL) 24 {} 25 26 Proxy::~Proxy() 27 {} 28 29 void Proxy::DoSomething1() 30 { 31 cout << "Proxy::DoSomething1" << endl; 32 } 33 34 void Proxy::DoSomething2() 35 { 36 cout << "Proxy::DoSomething2" << endl; 37 } 38 39 void Proxy::Request() 40 { 41 if(NULL == this->_subject) 42 { 43 this->_subject = new ConcreteSubject(); 44 } 45 46 this->DoSomething1();//表示額外附加的操作 47 48 this->_subject->Request();//代理的實體類操作 49 50 this->DoSomething2();//表示額外附加的操作 51 }
Main.cpp
1 #include "Proxy.h" 2 3 int main() 4 { 5 Proxy* proxy = new Proxy(); 6 proxy->Request(); 7 8 return 0; 9 }