在咱們的生活中,常常會遇到須要什麼東西,可是本身又不是很方便或者對方不是很方便,則就須要中間的一個代理人去解決。例如代購。
在軟件開發中,也會遇到這樣的問題。有些對象有時候會因爲網絡或其餘的障礙,以致於不可以或者不能直接訪問到這些對象,若是直接訪問對象給系統帶來沒必要要的複雜性,這時候能夠在客戶端和目標對象之間增長一層中間層,讓代理對象代替目標對象,而後客戶端只須要訪問代理對象,由代理對象去幫咱們去請求目標對象並返回結果給客戶端,這樣的一個解決思路就是今天要介紹的代理模式。設計模式
代理是一種結構型設計模式, 讓你能提供真實服務對象的替代品給客戶端使用。 代理接收客戶端的請求並進行一些處理 (訪問控制和緩存等), 而後再將請求傳遞給服務對象。
代理對象擁有和服務對象相同的接口, 這使得當其被傳遞給客戶端時可與真實對象互換。緩存
代理模式所涉及的角色有三個:安全
抽象主題角色(Person):聲明瞭真實主題和代理主題的公共接口,這樣一來在使用真實主題的任何地方均可以使用代理主題。服務器
代理主題角色(Friend):代理主題角色內部含有對真實主題的引用,從而能夠操做真實主題對象;代理主題角色負責在須要的時候建立真實主題對象;代理角色一般在將客戶端調用傳遞到真實主題以前或以後,都要執行一些其餘的操做,而不是單純地將調用傳遞給真實主題對象。例如這裏的PreBuyProduct和PostBuyProduct方法就是代理主題角色所執行的其餘操做。網絡
真實主題角色(RealBuyPerson):定義了代理角色所表明的真是對象。工具
代理模式按照使用目的能夠分爲如下幾種:性能
在上面全部種類的代理模式中,虛擬代理、遠程代理、智能引用代理和保護代理較爲常見的代理模式。測試
例如項目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管理工具成功
當沒法或不想直接引用某個對象或訪問某個對象存在困難時,能夠經過代理對象來間接訪問。使用代理模式主要有兩個目的:一是保護目標對象,二是加強目標對象。
因爲代理模式有許多分類,應用場景又適於多種狀況: