1. 程式人生 > >(38)C#設計模式——代理模式(Proxy Pattern)

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

引言

在軟體開發過程中,有些物件有時候會由於網路或其他障礙,以至於不能夠或者不能直接訪問到這些物件,如果直接訪問物件給系統帶來不必要的複雜性,這時候可以在客戶端和目標物件之間增加一層中間層,讓代理物件代替目標物件,然後客戶端只需要訪問代理物件,由代理物件去幫我們請求目標物件並返回結果給客戶端,這就是代理模式的實現思路。

詳細介紹

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

  • 遠端(Remote)代理:為一個位於不同的地址空間的物件提供一個局域代表物件。這個不同的地址空間可以是本電腦中,也可以在另外一臺電腦中。最典型的例子就是——客戶端呼叫Web伺服器或WCF服務
  • 虛擬(virtual)代理:根據需要建立一個資源消耗較大的物件,使得物件只在需要時才會被真正建立
  • Copy-on-Write代理:虛擬代理的一種,把複製拖延到只有在客戶端需要時,才真正採取行動
  • 保護(Protecte or Access)代理:控制一個物件的訪問,可以給不同的使用者提供不同級別的使用許可權
  • 防火牆(Firewall)代理:保護目標不受惡意使用者接近
  • 智慧引用(Smart Reference)代理:當一個物件被引用時,提供一些額外的操作,比如將對此物件呼叫的次數記錄下來等
  • Cache代理:為某一個目標操作的結果提供臨時的儲存空間,以便多個客戶端可以使用這些結果

上述代理模式中,虛擬代理、遠端代理、智慧引用代理和保護代理是比較常見的代理模式。

定義:

代理模式——

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

實現

在現實生活中,如果有朋友出國的情況下,我們經常會託這位朋友幫忙帶一些電子產品或者化妝品等東西,在這個場景中,出國的朋友就是一個代理,是他朋友的一個代理,由於他朋友不能去國外買東西,他卻可以,所以朋友叫他幫忙帶一下東西。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace _29ProfxyPatternDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            Person proxy = new Friend();
            proxy.BuyProduct();
        }
    }
    // 抽象主題角色
    public abstract class Person
    {
        public abstract void BuyProduct();
    }
    //真實主題角色
    public class RealBuyPerson : Person
    {
        public override void BuyProduct()
        {
            Console.WriteLine("幫我買一個IPhone和一臺蘋果電腦");
        }
    }
    //代理角色
    public class Friend : Person
    {
        //引用真實主題例項
        RealBuyPerson realSubject;
        public override void BuyProduct()
        {
            Console.WriteLine("通過代理類訪問真實實體物件的方法");
            if (realSubject == null)
            {
                realSubject = new RealBuyPerson();
            }
            this.PreBuyProduct();
            //呼叫真實主題方法
            realSubject.BuyProduct();
            this.PostBuyProduct();
        }
        //代理角色執行的一些操作
        public void PreBuyProduct()
        {
            Console.WriteLine("清單,張三:相機;李四:IPhone...............");
        }
        //代理角色需要對買的東西進行分類
        public void PostBuyProduct()
        {
            Console.WriteLine("買完了,現在把東西分一下,相機是張三的,IPhone是李四的............");
        }
    }
}

角色

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

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

真實主題角色(RealBuyPerson):定義了代理角色所代表的具體物件

tips:在實際開發過程中,我們在客戶端新增服務引用的時候,在客戶程式中會新增一些額外的類,在客戶端生成的類扮演著代理主題角色,我們客戶端也是直接呼叫這些代理角色來訪問遠端伺服器提供的操作。

優缺點

優點:

  • 代理模式能夠將呼叫用於真正被呼叫的物件隔離,在一定程度上降低了系統的耦合度
  • 代理物件在客戶端和目標物件之間起到一箇中介的作用,這樣可以起到對目標物件的保護。代理物件可以在對目標物件發出請求之前進行一個額外的操作,例如許可權檢查等

缺點:

  • 由於在客戶端和真實主題主鍵增加了一個代理物件,所以會造成請求的處理速度變慢
  • 實現代理類也需要額外的工作,從而增加了系統的實現複雜度

總結

代理模式提供了對目標物件訪問的代理。到這裡,結構型模式也介紹完畢。結構型模式包括:介面卡模式、橋接模式、裝飾者模式、組合模式、外觀模式、享元模式和代理模式。後面介紹行為模式。