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

引言

在咱們的生活中,常常會遇到須要什麼東西,可是本身又不是很方便或者對方不是很方便,則就須要中間的一個代理人去解決。例如代購。
在軟件開發中,也會遇到這樣的問題。有些對象有時候會因爲網絡或其餘的障礙,以致於不可以或者不能直接訪問到這些對象,若是直接訪問對象給系統帶來沒必要要的複雜性,這時候能夠在客戶端和目標對象之間增長一層中間層,讓代理對象代替目標對象,而後客戶端只須要訪問代理對象,由代理對象去幫咱們去請求目標對象並返回結果給客戶端,這樣的一個解決思路就是今天要介紹的代理模式。設計模式

概念

代理是一種結構型設計模式, 讓你能提供真實服務對象的替代品給客戶端使用。 代理接收客戶端的請求並進行一些處理 (訪問控制和緩存等), 而後再將請求傳遞給服務對象。
代理對象擁有和服務對象相同的接口, 這使得當其被傳遞給客戶端時可與真實對象互換。緩存

結構圖

代理模式所涉及的角色有三個:安全

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

代理主題角色(Friend):代理主題角色內部含有對真實主題的引用,從而能夠操做真實主題對象;代理主題角色負責在須要的時候建立真實主題對象;代理角色一般在將客戶端調用傳遞到真實主題以前或以後,都要執行一些其餘的操做,而不是單純地將調用傳遞給真實主題對象。例如這裏的PreBuyProduct和PostBuyProduct方法就是代理主題角色所執行的其餘操做。網絡

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

分類

代理模式按照使用目的能夠分爲如下幾種:性能

  1. 遠程(Remote)代理:爲一個位於不一樣的地址空間的對象提供一個局域表明對象。這個不一樣的地址空間能夠是本電腦中,也能夠在另外一臺電腦中。最典型的例子就是——客戶端調用Web服務或WCF服務。
  2. 虛擬(Virtual)代理:根據須要建立一個資源消耗較大的對象,使得對象只在須要時纔會被真正建立。
  3. Copy-on-Write代理:虛擬代理的一種,把複製(或者叫克隆)拖延到只有在客戶端須要時,才真正採起行動。
  4. 保護(Protect or Access)代理:控制一個對象的訪問,能夠給不一樣的用戶提供不一樣級別的使用權限。
  5. 防火牆(Firewall)代理:保護目標不讓惡意用戶接近。
  6. 智能引用(Smart Reference)代理:當一個對象被引用時,提供一些額外的操做,好比將對此對象調用的次數記錄下來等。
  7. Cache代理:爲某一個目標操做的結果提供臨時的存儲空間,以便多個客戶端能夠這些結果。

在上面全部種類的代理模式中,虛擬代理、遠程代理、智能引用代理和保護代理較爲常見的代理模式。測試

實現

例如項目A的PM須要購買一個測試工具,可是測試工具的運營商在國外,本身過去不是很方便,因此須要找一個代理商幫助本身去購買。this

下面就實現此購買的例子:spa

using System;


namespace Proxy
{
    class Program
    {
        static void Main(string[] args)
        {

            ProgramManagement PM = new ProgramManagement();
            PM.BuyToolName = "Bug管理工具";
            PM.BuyTestTool();

            ProxyBuyTestTool Tynam = new ProxyBuyTestTool(PM);
            Tynam.BuyTestTool();


            Console.ReadKey();
        }
    }

    public interface ITestTool
    {
        void BuyTestTool();
    }

    public class ProgramManagement : ITestTool
    {

        public string BuyToolName;
        public void BuyTestTool()
        {
            Console.WriteLine($"項目A須要找一個代理商購買國外的一款{this.BuyToolName}的測試工具");
        }
    }

    public class ProxyBuyTestTool : ITestTool
    {
        private ProgramManagement _pm;

        public ProxyBuyTestTool(ProgramManagement pm)
        {
            this._pm = pm;
        }

        public void BuyTestTool()
        {
            Console.WriteLine($"幫助項目A購買測試工具{this._pm.BuyToolName}成功");
        }

    }

}

運行後結果

項目A須要找一個代理商購買國外的一款Bug管理工具的測試工具
幫助項目A購買測試工具Bug管理工具成功

使用場景

當沒法或不想直接引用某個對象或訪問某個對象存在困難時,能夠經過代理對象來間接訪問。使用代理模式主要有兩個目的:一是保護目標對象,二是加強目標對象。

因爲代理模式有許多分類,應用場景又適於多種狀況:

  • 遠程代理,這種方式一般是爲了隱藏目標對象存在於不一樣地址空間的事實,方便客戶端訪問。例如,用戶申請某些網盤空間時,會在用戶的文件系統中創建一個虛擬的硬盤,用戶訪問虛擬硬盤時實際訪問的是網盤空間。
  • 虛擬代理,這種方式一般用於要建立的目標對象開銷很大時。例如,下載一幅很大的圖像須要很長時間,因某種計算比較複雜而短期沒法完成,這時能夠先用小比例的虛擬代理替換真實的對象,消除用戶對服務器慢的感受。
  • 安全代理,這種方式一般用於控制不一樣種類客戶對真實對象的訪問權限。
  • 智能指引,主要用於調用目標對象時,代理附加一些額外的處理功能。例如,增長計算真實對象的引用次數的功能,這樣當該對象沒有被引用時,就能夠自動釋放它。
  • 延遲加載,指爲了提升系統的性能,延遲對目標的加載。例如,Hibernate 中就存在屬性的延遲加載和關聯表的延時加載。

優缺點

優勢:

  • 代理模式在客戶端與目標對象之間起到一箇中介做用和保護目標對象的做用。
  • 代理對象能夠擴展目標對象的功能。
  • 代理模式能將客戶端與目標對象分離,在必定程度上下降了系統的耦合度,增長了程序的可擴展性。

缺點:

  • 代理模式會形成系統設計中類的數量增長。
  • 在客戶端和目標對象之間增長一個代理對象,會形成請求處理速度變慢。
  • 增長了系統的複雜度。
相關文章
相關標籤/搜索