1. 程式人生 > >設計模式(九)——代理模式

設計模式(九)——代理模式

設計模式 代理模式

設計模式(九)——代理模式

一、代理模式簡介

1、代理模式簡介

代理模式是為其他對象提供一種代理以控制對對象的訪問。

常見代理模式如下:

A遠程(Remote)代理:為一個位於不同的地址空間的對象提供一個局域代表對象。不同的地址空間可以是在本機器中,也可是在另一臺機器中。遠程代理又叫做大使(Ambassador為一個對象在不同的地址空間提供局部代表可以隱藏一個對象存在於不同地址空間的事實。

B虛擬(Virtual)代理:根據需要創建一個資源消耗較大的對象,使得此對象只在需要時才會被真正創建。

CCopy-on-Write代理:虛擬代理的一種。把復制(克隆)拖延到只有在客戶端需要時,才真正采取行動。

D保護(Protect or Access)代理:控制對一個對象的訪問,如果需要,可以給不同的用戶提供不同級別的使用權限。 用來控制真實對象訪問時的權限。一般用於對象應該有不同的訪問權限的時候。

ECache代理:為某一個目標操作的結果提供臨時的存儲空間,以便多個客戶端可以共享這些結果。 防火墻(Firewall)代理:保護目標,不讓惡意用戶接近。 同步化(Synchronization)代理:使幾個用戶能夠同時使用一個對象而沒有沖突。

F智能引用(Smart Reference)代理:當一個對象被引用時,提供一些額外的操作,比如將對此對象調用的次數記錄下來等。 當調用真實的對象時,代理處理另外一些事。如計算真實對象的引用次數,當對象沒有引用時,可以自動釋放;或當第一次引用一個持久對象時,將

對象裝入內存;或在訪問一個實際對象前,檢查是否已經鎖定,以確保其他對象不能改變它。

在所有種類的代理模式中,虛擬(Virtual)代理、遠程(Remote)代理、智能引用代理(Smart Reference Proxy)和保護(Protect or Access)代理是最為常見的代理模式。

技術分享

代理模式

本質是在訪問對象的時候引入了一定程度的間接性,由於間接性訪問對象,可以附加多種用途。

2、代理模式角色

Subject:聲明了真實主題ConcreteSubject和代理主題Proxy的共同接口,在任何使用真實主題的地方都可以使用代理主題。

Proxy:代理主題角色內部含有對真實主題ConcreteSubject的引用,從而可以在任何時候操作真實主題對象;代理主題角色提供一個與真實主題角色相同的接口,以便可以在任何時候都可以替代真實主題;控制真實主題的應用,負責在需要的時候創建真實主題對象(和刪除真實主題對象);代理角色通常在將客戶端調用傳遞給真實的主題之前或之後,都要執行某個操作,而不是單純的將調用傳遞給真實主題對象。

ConcreteSubject:定義了代理角色所代表的真實對象。

3、代理模式優缺點

優點:

A代理模式能夠協調調用者和被調用者,在一定程度上降低了系統的耦合度。

B職責清晰實現好內部結構就可以,具體客戶要求由代理進行分化

C高擴展性具體主題角色隨時變化,只要實現了接口,無論如何都逃不出代理的手掌,所以代理無論如何都是可以使用的

D遠程代理使得客戶端可以訪問在遠程機器上的對象,遠程機器可能具有更好的計算性能與處理速度,可以快速響應並處理客戶端請求。

E虛擬代理通過使用一個小對象來代表一個大對象,可以減少系統資源的消耗,對系統進行優化並提高運行速度。

F保護代理可以控制對真實對象的使用權限。

缺點:

A由於在客戶端和真實主題之間增加了代理對象,因此有些類型的代理模式可能會造成請求的處理速度變慢。

B實現代理模式需要額外的工作,有些代理模式的實現非常復雜。

4、代理模式使用場景

代理模式使用場景:

A遠程代理為一個對象在不同的地址空間提供局部代表可以隱藏一個對象存在於不同地址空間的事實。

B虛擬代理根據需要創建開銷很大的對象。通過虛擬代理來存放實例化需要很長時間的真實對象。例如:圖片加載的時候。

C安全代理用來控制真是對象訪問時的權限。

D智能指引當調用真實的對象的時候,代理處理另外一些事。

如果用戶不能直接訪問真實角色,只能訪問代理,則需要讓代理自動生成一個真實角色對象。

適配器模式中適配器為所適配的對象提供了一個不同的接口代理模式中代理提供的接口與實體的接口相同裝飾模式的目的是為對象添加功能,而代理模式則控制對對象的訪問。

二、代理模式實現

Subject抽象類:

#ifndef SUBJECT_H

#define SUBJECT_H

#include <iostream>

using namespace std;

//定義了Proxy和ConcreteSubject的公有接口

class Subject

{

public:

virtual ~Subject(){}

virtual void request() = 0;

protected:

Subject(){}

};

#endif // SUBJECT_H

ConcreteSubject真實主題類:

#ifndef CONCRETESUBJECT_H

#define CONCRETESUBJECT_H

#include "Subject.h"

//定義真實主題類

class ConcreteSubject : public Subject

{

public:

ConcreteSubject(){}

~ConcreteSubject(){}

void request()

{

cout << "ConcreteSubject::request" << endl;

}

};

#endif // CONCRETESUBJECT_H

Proxy代理類:

#ifndef PROXY_H

#define PROXY_H

#include "Subject.h"

#include "ConcreteSubject.h"

//定義代理類

class Proxy : public Subject

{

public:

Proxy():m_pSubject(NULL){}

~Proxy()

{

delete m_pSubject;

m_pSubject = NULL;

}

void request()

{

if(NULL == m_pSubject)

{

m_pSubject = new ConcreteSubject();

}

//額外操作

doSomethingA();

//代理實體的操作

m_pSubject->request();

//額外操作

doSomethingB();

}

void doSomethingA()

{

cout << "Proxy::doSomethingA" << endl;

}

void doSomethingB()

{

cout << "Proxy::doSomethingB" << endl;

}

private:

Subject* m_pSubject;

};

#endif // PROXY_H

客戶調用程序:

#include "Proxy.h"

int main()

{

//使用代理取代ConcreteSubject

Proxy* proxy = new Proxy();

proxy->request();

delete proxy;

return 0;

}


本文出自 “生命不息,奮鬥不止” 博客,謝絕轉載!

設計模式(九)——代理模式