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

設計模式(C#)——11代理模式

推薦閱讀:

前言

       在軟體開發過程中,當無法直接訪問某個物件或訪問某個物件存在困難時,我們希望可以通過一箇中介來間接訪問,這就是今天我們要研究的代理模式。

介紹

       代理模式:為其他物件提供一種代理以控制對這個物件的訪問,一個類代表另一個類的功能。為了保證客戶端使用的透明性,所訪問的真實物件與代理物件需要實現相同的介面。

代理模式的元素:

(1) Subject(抽象主題):它聲明瞭真實主題和代理主題的共同介面,這樣一來在任何使用真實主題的地方都可以使用代理主題,客戶端通常需要針對抽象主題角色進行程式設計。
(2) Proxy(代理主題):它包含了對真實主題的引用,從而可以在任何時候操作真實主題物件;在代理主題角色中提供一個與真實主題角色相同的介面,以便在任何時候都可以替代真實主題;代理主題角色還可以控制對真實主題的使用,負責在需要的時候建立和刪除真實主題物件,並對真實主題物件的使用加以約束。通常,在代理主題角色中,客戶端在呼叫所引用的真實主題操作之前或之後還需要執行其他操作,而不僅僅是單純呼叫真實主題物件中的操作。
(3) RealSubject(真實主題):它定義了代理角色所代表的真實物件,在真實主題角色中實現了真實的業務操作,客戶端可以通過代理主題角色間接呼叫真實主題角色中定義的操作。

下面舉個例子來介紹下代理模式:

       假設有一群人是互相的好朋友,其中A和B吵架了,A想和B和好,但是由於不好意思直接說,因此就隨便找了剩下人中的一個(假設是C),想C幫A給B道歉。此時把除AB剩餘的人作為抽象主題,把A作為代理主題,C就是真實主題。
1.建立抽象主題

abstract class Friends
{
    public abstract void Apology(string msg);
    
    protected virtual void Apologyed() 
    {
Console.WriteLine("幫忙道歉完成~~~~~"); } }

2.真實主題

class Friend_C: Friends
{
    public override void Apology(string msg)
    {
        //業務方法具體實現程式碼
        Console.WriteLine(msg);
        Apologyed();
    }
    protected override void Apologyed() {
		Console.WriteLine("Friend_C幫忙道歉完成~~~~~");
	}
}

3.代理類

class Friend_A: Friends
{
    private Friend_C friend_C= new Friend_C(); //維持一個對真實主題物件的引用
 
    public override void Apology(string msg) 
    {
         friend_C.Apology(msg);
    }
}

4.使用代理模式

public class Program {
 
	private static Friend_A friend_A= null;
 
	public static void Main(string[] args) {
		friend_A= new Friend_A();
		friend_A.Apology("對不起B,我(A)錯了");
		Console.ReadKey();
	}
}

5.整合後的程式碼

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace 代理模式
{
    abstract class Friends
	{
	    public abstract void Apology(string msg);
	    
	    protected virtual void Apologyed() 
	    {
			Console.WriteLine("幫忙道歉完成~~~~~");
		}
	}
		
	class Friend_C : Friends
	{
	    public override void Apology(string msg)
	    {
	        //業務方法具體實現程式碼
	        Console.WriteLine(msg);
	        Apologyed();
	    }
	    protected override void Apologyed() {
			Console.WriteLine("Friend_C幫忙道歉完成~~~~~");
		}
	}
			
	class Friend_A : Friends
	{
	    private Friend_C friend_C = new Friend_C (); //維持一個對真實主題物件的引用
	 
	    public override void Apology(string msg) 
	    {
	         friend_C .Apology(msg);
	    }
	}
	
	public class Program 
	{
		private static Friend_A friend_A= null;
	 
		public static void Main(string[] args) 
		{
			friend_A= new Friend_A ();
			friend_A.Apology("對不起B,我(A)錯了");
			Console.ReadKey();
		}
	}
}

優缺點

優點:
      職責清晰;高擴充套件性;智慧化。
缺點:
      由於在客戶端和真實主題之間增加了代理物件,因此有些型別的代理模式可能會造成請求的處理速度變慢;實現代理模式需要額外的工作,有些代理模式的實現非常複雜。

總結

       在實際開發過程中,代理類的實現比上述程式碼要複雜很多,代理模式根據其目的和實現方式不同可分為很多種類,其中常用的幾種代理模式簡要說明如下:

(1) 遠端代理(Remote Proxy):為一個位於不同的地址空間的物件提供一個本地的代理物件,這個不同的地址空間可以是在同一臺主機中,也可是在另一臺主機中,遠端代理又稱為大使(Ambassador)。

(2) 虛擬代理(Virtual Proxy):如果需要建立一個資源消耗較大的物件,先建立一個消耗相對較小的物件來表示,真實物件只在需要時才會被真正建立。

(3) 保護代理(Protect Proxy):控制對一個物件的訪問,可以給不同的使用者提供不同級別的使用許可權。

(4) 緩衝代理(Cache Proxy):為某一個目標操作的結果提供臨時的儲存空間,以便多個客戶端可以共享這些結果。

(5) 智慧引用代理(Smart Reference Proxy):當一個物件被引用時,提供一些額外的操作,例如將物件被呼叫的次數記錄下來等。