定義
代理模式(Proxy Pattern) 是一種結構型設計模式,它通過提供一個代理對象來控制對目標對象的訪問。代理對象作為客戶端與目標對象之間的中介,間接地訪問目標對象的功能。代理模式可以在不改變目標對象的情況下增加一些額外的功能,如延遲加載、安全控制、日志記錄等。
基本思想
代理對象:代理模式引入了一個中介對象(代理對象)來訪問真實的對象。代理對象控制對真實對象的訪問,并可以在訪問真實對象之前或之后加入額外的功能。
目標對象:代理模式的核心是需要被代理的對象,它實現了實際的業務邏輯。
客戶端:客戶端通過代理對象間接調用目標對象的方法,而不直接訪問目標對象。
適用場景
代理模式適用于以下場景:
- 控制訪問:當需要控制對某個對象的訪問時,可以使用代理模式。比如,代理模式可以限制某些操作,或者在目標對象沒有初始化時,延遲加載目標對象。
- 延遲加載:在需要時才創建目標對象,而不是在系統初始化時創建,這樣可以節省資源。
- 緩存:通過代理模式,代理對象可以緩存目標對象的結果,避免重復計算。
- 日志記錄:代理對象可以在方法執行前后記錄日志,確保目標對象的行為被正確監控。
- 遠程訪問:代理模式可用于實現遠程訪問對象,客戶端與代理對象交互,而代理對象負責與遠程目標對象進行通信。
類設計
代碼實現解析
- 設計目標:代理模式實現任務處理
我們設計一個簡單的場景,其中 ISubject 是任務處理接口,RealSubject 是具體的任務處理類,SubjectProxy 是代理類,它負責對 RealSubject 的間接訪問。
#include <iostream>
#include <string>
using namespace std;// 定義Subject接口
class ISubject {
public:virtual void process() = 0;virtual ~ISubject() {}
};// 真實主題類(RealSubject)
class RealSubject : public ISubject {
public:void process() override {cout << "RealSubject: Processing the task." << endl;}
};// 代理類(SubjectProxy)
class SubjectProxy : public ISubject {
private:RealSubject* realSubject;public:SubjectProxy() : realSubject(nullptr) {}void process() override {// 代理對象在訪問目標對象之前做一些處理(如延遲加載、權限檢查等)cout << "Proxy: Checking access rights..." << endl;if (!realSubject) {// 延遲加載目標對象realSubject = new RealSubject();cout << "Proxy: Creating RealSubject instance..." << endl;}// 代理對象調用真實主題的方法realSubject->process();}~SubjectProxy() {delete realSubject; // 確保釋放真實主題對象的資源}
};// 客戶端類
class ClientApp {
private:ISubject* subject;public:ClientApp() {subject = new SubjectProxy(); // 客戶端通過代理類訪問任務}void DoTask() {// 客戶端通過代理對象執行任務subject->process();}~ClientApp() {delete subject;}
};int main() {ClientApp app;app.DoTask(); // 通過代理對象處理任務return 0;
}
輸出:
Proxy: Checking access rights...
Proxy: Creating RealSubject instance...
RealSubject: Processing the task.客戶端通過 ClientApp 調用 subject->process(),
但實際執行的是通過 SubjectProxy 代理對象的 process() 方法。代理對象首先檢查訪問權限(這里是模擬操作),
然后如果目標對象尚未創建,則延遲創建 RealSubject 實例并執行任務。
類設計分析
1.ISubject(接口/抽象類):
- 定義了代理類和真實對象共同的接口。在本例中,process() 方法是客戶端與代理類和真實類交互的唯一方式。
2.RealSubject(真實主題):
- RealSubject 是實際執行任務的類,它提供了業務邏輯的實現。
- 在 process() 方法中,RealSubject 處理實際的任務。
3.SubjectProxy(代理類):
- 代理類實現了 ISubject 接口,負責控制對 RealSubject 的訪問。代理類可以在調用 RealSubject 的方法之前執行一些操作(如延遲加載、權限驗證、日志記錄等)。
- 在 process() 方法中,代理對象會檢查是否已經創建了 RealSubject 實例,如果沒有,則創建一個實例并調用 process()。
4.ClientApp(客戶端):
- 客戶端通過 ISubject 接口與 SubjectProxy(代理對象)交互,而不直接與 RealSubject 進行交互。客戶端只調用 process() 方法,而無需關心代理對象如何處理目標對象的訪問。
代理模式的優缺點
優點:
- 控制訪問:代理模式可以控制對目標對象的訪問,并增加附加功能,如懶加載、日志、權限驗證等。
- 提高效率:通過延遲加載(懶加載),可以在需要時才創建目標對象,從而節省資源。
- 解耦:客戶端不需要直接與目標對象交互,代理類充當了客戶端和目標對象之間的中介,降低了系統的耦合性。
- 附加功能:可以在代理類中為目標對象添加額外的功能,如緩存、日志、權限檢查等,而不修改目標對象的代碼。
缺點
- 增加復雜度:代理模式通過引入額外的類增加了系統的復雜度,特別是在目標對象復雜時。
- 性能開銷:代理類通常會引入一定的性能開銷,尤其是在頻繁的代理操作中,可能會影響系統的性能。
- 不可避免的代理層:代理模式在某些情況下可能導致不必要的中間層,尤其是當目標對象的接口已經足夠簡潔時。
適用場景
代理模式適用于以下場景:
- 延遲加載:當對象的創建成本較高時,可以使用代理模式進行延遲加載。
- 訪問控制:當需要對目標對象的訪問進行控制時(如權限驗證、緩存等),可以使用代理模式。
- 資源保護:代理模式可用于保護目標對象的資源,如防止頻繁創建和銷毀實例。
- 遠程代理:在分布式系統中,代理模式可以用來控制客戶端與遠程對象之間的通信。
常見應用場景:
- 虛擬代理:延遲加載目標對象,直到真正需要它時才創建實例。
- 保護代理:限制客戶端對某些操作的訪問,進行權限檢查。
- 遠程代理:客戶端通過代理與遠程對象進行交互,代理負責與遠程服務器通信。
- 智能代理:增加一些額外的功能,如緩存、日志、事務管理等。
總結
代理模式通過引入代理類,允許客戶端通過代理間接訪問目標對象,并能在不改變目標對象的情況下,增加一些額外的功能,如延遲加載、訪問控制、日志記錄等。代理模式能有效地解耦客戶端和目標對象,簡化客戶端與目標對象之間的交互,同時增加系統的靈活性。