天天看點

C#設計模式(13)——代理模式(Proxy Pattern)

在軟體開發過程中,有些對象有時候會由于網絡或其他的障礙,以至于不能夠或者不能直接通路到這些對象,如果直接通路對象給系統帶來不必要的複雜性,這時候可以在用戶端和目标對象之間增加一層中間層,讓代理對象代替目标對象,然後用戶端隻需要通路代理對象,由代理對象去幫我們去請求目标對象并傳回結果給用戶端,這樣的一個解決思路就是今天要介紹的代理模式。

代理模式按照使用目的可以分為以下幾種:

遠端(Remote)代理:為一個位于不同的位址空間的對象提供一個局域代表對象。這個不同的位址空間可以是本電腦中,也可以在另一台電腦中。最典型的例子就是——用戶端調用Web服務或WCF服務。

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

Copy-on-Write代理:虛拟代理的一種,把複制(或者叫克隆)拖延到隻有在用戶端需要時,才真正采取行動。

保護(Protect or Access)代理:控制一個對象的通路,可以給不同的使用者提供不同級别的使用權限。

防火牆(Firewall)代理:保護目标不讓惡意使用者接近。

智能引用(Smart Reference)代理:當一個對象被引用時,提供一些額外的操作,比如将對此對象調用的次數記錄下來等。

Cache代理:為某一個目标操作的結果提供臨時的存儲空間,以便多個用戶端可以這些結果。

在哦上面所有種類的代理模式中,虛拟代理、遠端代理、智能引用代理和保護代理較為常見的代理模式。下面讓我們具體看看代理模式的具體定義。

代理模式——就是給某一個對象提供一個代理,并由代理對象控制對原對象的引用。在一些情況下,一個客戶不想或者不能直接引用一個對象,而代理對象可以在用戶端和目标對象之間起到中介的作用。例如電腦桌面的快捷方式就是一個代理對象,快捷方式是它所引用的程式的一個代理。

看完代理模式的描述之後,下面以一個生活中的例子來解釋下代理模式,在現實生活中,如果有同僚出國或者朋友出國的情況下,我們經常會拖這位朋友幫忙帶一些電子産品或化妝品等東西,這個場景中,出國的朋友就是一個代理,他(她)是他(她)朋友的一個代理,由于他朋友不能去國外買東西,他卻可以,是以朋友們都托他幫忙帶一些東西的。下面就以這個場景來實作下代理模式,具體代碼如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

<code>// 用戶端調用</code>

<code>    </code><code>class</code> <code>Client</code>

<code>    </code><code>{</code>

<code>        </code><code>static</code> <code>void</code> <code>Main(</code><code>string</code><code>[] args)</code>

<code>        </code><code>{</code>

<code>            </code><code>// 建立一個代理對象并送出請求</code>

<code>            </code><code>Person proxy = </code><code>new</code> <code>Friend();</code>

<code>            </code><code>proxy.BuyProduct();</code>

<code>            </code><code>Console.Read();</code>

<code>        </code><code>}</code>

<code>    </code><code>}</code>

<code>    </code><code>// 抽象主題角色</code>

<code>    </code><code>public</code> <code>abstract</code> <code>class</code> <code>Person</code>

<code>        </code><code>public</code> <code>abstract</code> <code>void</code> <code>BuyProduct();</code>

<code>    </code><code>//真實主題角色</code>

<code>    </code><code>public</code> <code>class</code> <code>RealBuyPerson : Person</code>

<code>        </code><code>public</code> <code>override</code> <code>void</code> <code>BuyProduct()</code>

<code>            </code><code>Console.WriteLine(</code><code>"幫我買一個IPhone和一台蘋果電腦"</code><code>);</code>

<code>    </code><code>// 代理角色</code>

<code>    </code><code>public</code> <code>class</code> <code>Friend:Person</code>

<code>        </code><code>// 引用真實主題執行個體</code>

<code>        </code><code>RealBuyPerson realSubject;</code>

<code>            </code><code>Console.WriteLine(</code><code>"通過代理類通路真實實體對象的方法"</code><code>);</code>

<code>            </code><code>if</code> <code>(realSubject == </code><code>null</code><code>)</code>

<code>            </code><code>{</code>

<code>                </code><code>realSubject = </code><code>new</code> <code>RealBuyPerson();</code>

<code>            </code><code>}</code>

<code>            </code><code>this</code><code>.PreBuyProduct();</code>

<code>            </code><code>// 調用真實主題方法</code>

<code>            </code><code>realSubject.BuyProduct();</code>

<code>            </code><code>this</code><code>.PostBuyProduct();</code>

<code>        </code><code>// 代理角色執行的一些操作</code>

<code>        </code><code>public</code> <code>void</code> <code>PreBuyProduct()</code>

<code>            </code><code>// 可能不知一個朋友叫這位朋友帶東西,首先這位出國的朋友要對每一位朋友要帶的東西列一個清單等</code>

<code>            </code><code>Console.WriteLine(</code><code>"我怕弄糊塗了,需要列一張清單,張三:要帶相機,李四:要帶Iphone..........."</code><code>);</code>

<code>                         </code> 

<code>        </code><code>// 買完東西之後,代理角色需要針對每位朋友需要的對買來的東西進行分類</code>

<code>        </code><code>public</code> <code>void</code> <code>PostBuyProduct()</code>

<code>            </code><code>Console.WriteLine(</code><code>"終于買完了,現在要對東西分一下,相機是張三的;Iphone是李四的.........."</code><code>);</code>

在上面的代碼中都有相應的注釋,這裡也不多解釋了。

看完代理模式的實作之後,下面就以上面的例子來分析下代理模式的類圖結構。具體的類圖如下所示:

C#設計模式(13)——代理模式(Proxy Pattern)

在上面類圖中,代理模式所涉及的角色有三個:

抽象主題角色(Person):聲明了真實主題和代理主題的公共接口,這樣一來在使用真實主題的任何地方都可以使用代理主題。

代理主題角色(Friend):代理主題角色内部含有對真實主題的引用,進而可以操作真實主題對象;代理主題角色負責在需要的時候建立真實主題對象;代理角色通常在将用戶端調用傳遞到真實主題之前或之後,都要執行一些其他的操作,而不是單純地将調用傳遞給真實主題對象。例如這裡的PreBuyProduct和PostBuyProduct方法就是代理主題角色所執行的其他操作。

真實主題角色(RealBuyPerson):定義了代理角色所代表的真是對象。

附:在實際開發過程中,我們在用戶端添加服務引用的時候,在客戶程式中會添加一些額外的類,在用戶端生成的類扮演着代理主題角色,我們用戶端也是直接調用這些代理角色來通路遠端服務提供的操作。這個是遠端代理的一個典型例子。

全面分析完代理模式之後,讓我們看看這個模式的優缺點:

優點:

代理模式能夠将調用用于真正被調用的對象隔離,在一定程度上降低了系統的耦合度;

代理對象在用戶端和目标對象之間起到一個中介的作用,這樣可以起到對目标對象的保護。代理對象可以在對目标對象送出請求之前進行一個額外的操作,例如權限檢查等。

缺點:

由于在用戶端和真實主題之間增加了一個代理對象,是以會造成請求的處理速度變慢

實作代理類也需要額外的工作,進而增加了系統的實作複雜度。

到這裡,代理模式的介紹就結束了,代理模式提供了對目标對象通路的代理。并且到這裡,結構型模式的介紹也結束了,結構型模式包括:擴充卡模式、橋接模式、裝飾者模式、組合模式、外觀模式、享元模式和代理模式,下面開始介紹行為型模式的第一個模式:模闆方法模式。

<a href="http://down.51cto.com/data/2363667" target="_blank">附件:http://down.51cto.com/data/2363667</a>

     本文轉自LearningHard 51CTO部落格,原文連結:http://blog.51cto.com/learninghard/1315891,如需轉載請自行聯系原作者