文章出處

索引

別名

  • Surrogate

意圖

為其他對象提供一種代理以控制對這個對象的訪問。

Provide a surrogate or placeholder for another object to control access to it.

結構

運行時一種可能的 Proxy 結構的對象圖:

參與者

Proxy

  • 保存一個引用使得代理可以訪問實體。若 RealSubject 和 Subject 的接口相同,Proxy 會引用 Subject。
  • 提供一個與 Subject 的接口相同的接口,這樣 Proxy 就可以用來代替實體。
  • 控制對實體的存取,并可能負責創建和刪除它。
  • 其他功能依賴于 Proxy 的類型:
    • 遠程代理(Remote Proxy)負責對請求及其參數進行編碼,并向不同地址空間中的實體發送已編碼的請求。
    • 虛擬代理(Virtual Proxy)可以緩存實體的附加信息,以便延遲對它的訪問。
    • 保護代理(Protection Proxy)檢查調用者是否具有實現一個請求所必須的訪問權限。

Subject

  • 定義 RealSubject 和 Proxy 的共用接口,這樣就在任何使用 RealSubject 的地方都可以使用 Proxy。

RealSubject

  • 定義 Proxy 所代表的實體。

適用性

下面是一些使用 Proxy 模式的常見情況:

  • 遠程代理(Remote Proxy)為一個對象在不同的地址空間提供局部代表。
  • 虛擬代理(Virtual Proxy)根據需要創建開銷很大的對象。
  • 保護代理(Protection Proxy)控制對原始對象的訪問。
  • 智能代理(Smart Proxy)在訪問對象時執行一些附件操作。

效果

  • Proxy 模式在訪問對象時引入了一定程度的間接性。
  • Proxy 模式可以對用戶隱藏 Copy-On-Write 優化方式。用 Proxy 延遲對象拷貝過程,僅當這個對象被修改時才進行真正的拷貝,用以大幅度降低拷貝大實體的開銷。

相關模式

  • Adapter 為它所適配的對象提供了一個不同的接口。Proxy 提供了與它的實體相同的接口
  • Decorator 的實現與 Proxy 相似,但目的不一樣。 Decorator 為對象添加功能,Proxy 則控制對對象的訪問。

實現

實現方式(一):使用相同 Subject 接口實現 Proxy。

對一個對象進行訪問控制的一個原因是為了只有在我們確實需要這個對象時才對它進行創建和初始化。

 1 namespace ProxyPattern.Implementation1
 2 {
 3   public abstract class Subject
 4   {
 5     public abstract string Name { get; }
 6     public abstract void Request();
 7   }
 8 
 9   public class ConcreteSubject : Subject
10   {
11     private string _name;
12 
13     public ConcreteSubject(string name)
14     {
15       _name = name;
16     }
17 
18     public override string Name { get { return _name; } }
19 
20     public override void Request()
21     {
22       // do something
23     }
24   }
25 
26   public class Proxy : Subject
27   {
28     private Subject _realSubject = null;
29     private string _name;
30 
31     public Proxy(string name)
32     {
33       _name = name;
34     }
35 
36     public override string Name { get { return _name; } }
37 
38     public override void Request()
39     {
40       if (_realSubject == null)
41         LoadRealSubject();
42 
43       _realSubject.Request();
44     }
45 
46     private void LoadRealSubject()
47     {
48       // do some heavy things
49       _realSubject = new ConcreteSubject(_name);
50     }
51   }
52 
53   public class Client
54   {
55     public void TestCase1()
56     {
57       Subject subject = new Proxy("SubjectName");
58       var subjectName = subject.Name;
59       subject.Request();
60     }
61   }
62 }

設計模式之美》為 Dennis Gao 發布于博客園的系列文章,任何未經作者本人同意的人為或爬蟲轉載均為耍流氓。


文章列表


不含病毒。www.avast.com
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()