前言
今天講的是結(jié)構(gòu)型設(shè)計(jì)模式中的最后一個(gè),這個(gè)模式也就是代理模式,在前段時(shí)間我寫的一篇關(guān)于正向代理和反向代理
<https://www.cnblogs.com/hulizhong/p/11268468.html>
的文章。雖說(shuō)此代理非彼代理。但是代理一詞還是具有相似的含義的。這里我們繼續(xù)使用文章中的代購(gòu)一個(gè)例子來(lái)講述一下代理模式吧,人不方便去購(gòu)買哪些物品,這時(shí)就有一個(gè)中間人,他來(lái)購(gòu)買。他代替我去購(gòu)買。他也就充當(dāng)了那個(gè)代理的職責(zé)。我們繼續(xù)往下看吧。
代理模式介紹
一、來(lái)由
在軟件系統(tǒng)的開放中,有一些對(duì)象存在,但是直接訪問(wèn)會(huì)給使用者帶來(lái)一些麻煩,或者使用起來(lái)不那么方便,這是就是需要一個(gè)代理對(duì)象來(lái)中間起到關(guān)鍵作用。通過(guò)這個(gè)代理對(duì)象進(jìn)行訪問(wèn),以來(lái)解決這些問(wèn)題。這也就是代理模式。
二、意圖
為其他對(duì)象提供一種代理以控制對(duì)這個(gè)對(duì)象的訪問(wèn)。
三、案例圖
?
?
?
四、代理模式代碼示例
看上面的案例圖,我們發(fā)現(xiàn)代理模式包含以下部分:
抽象角色:定義代理角色和真實(shí)角色的公共接口,這樣來(lái)說(shuō)使用真實(shí)角色的地方就可以使用代理角色。
代理角色:包含對(duì)真實(shí)角色的引用,這樣可以操作真實(shí)角色,代理角色不僅僅只是調(diào)用真實(shí)角色,也會(huì)執(zhí)行其他的操作。
真實(shí)角色:定義了代理角色所代表的真實(shí)角色。
這里我們使用的是一個(gè)代理進(jìn)行代購(gòu)的案例來(lái)進(jìn)行講述,讓我們一起看看如何實(shí)現(xiàn)的吧:
?
namespace Proxy_Pattern { class ProxyPattern { } #region 抽象角色——抽象需要做的事情的方法
public abstract class Buy { public abstract void BuyFun(string Name); }
#endregion #region 真實(shí)角色——實(shí)現(xiàn)抽象的方法 public class RealBuy : Buy { public override
void BuyFun(string Name) { Console.WriteLine($"幫我購(gòu)買{Name}"); } } #endregion
#region 代理角色——代購(gòu) public class ProxyBuy : Buy { public RealBuy realBuy; public
ProxyBuy() { realBuy= new RealBuy(); } public override void BuyFun(string Name)
{var flag= this.AllowBuy(Name); if (!flag) { Console.WriteLine("違禁品不允許購(gòu)買"); }
else { realBuy.BuyFun(Name); Recording(Name); } } /// <summary> ///
代理模式中的額外操作。例如購(gòu)買的東西,不可能啥東西都買。需要對(duì)購(gòu)買的東西進(jìn)行檢查/// </summary> /// <param name="Name">
購(gòu)買的東西</param> /// <returns></returns> public bool AllowBuy(string Name) { if
(Name!="違禁品") { return true; } return false; } /// <summary> /// 對(duì)購(gòu)買的東西進(jìn)行記錄 ///
</summary> /// <param name="Name"></param> public void Recording(string Name) {
Console.WriteLine($"這次代購(gòu)購(gòu)買了{(lán)Name}"); } } #endregion }
?
namespace Proxy_Pattern { class Program { static void Main(string[] args) { //
初始化代理對(duì)象 Buy buy = new ProxyBuy(); //代理對(duì)象進(jìn)行處理事務(wù) buy.BuyFun("化妝品"); buy.BuyFun("
違禁品"); } } }
?
使用場(chǎng)景及優(yōu)缺點(diǎn)
不管是使用怎樣的代理,都是在軟件系統(tǒng)中增加一個(gè)中間層次,這種方式對(duì)于解決一些復(fù)雜問(wèn)題或者對(duì)象之間的問(wèn)題提供了較大方便。代理模式又劃分了許多的類型,待會(huì)下面我們會(huì)一一介紹的。代理模式并不要求保持各個(gè)類之間的接口的一致性,代理模式的重點(diǎn)是間接控制,中間層次管理。
一、使用場(chǎng)景
根據(jù)代理模式的職責(zé)我們可以分為以下的使用場(chǎng)景:
遠(yuǎn)程代理:為兩個(gè)不同地址的對(duì)象信息代理,典型例子就是客戶端與服務(wù)之間??蛻舳苏{(diào)用服務(wù)。
虛擬代理:根據(jù)需要?jiǎng)?chuàng)建一個(gè)資源消耗較大的對(duì)象,使得對(duì)象在需要的時(shí)候才會(huì)被調(diào)用。
Copy-on-Write 代理:屬于虛擬代理的一種,把復(fù)制或者克隆拖延到客戶端需要的時(shí)候才執(zhí)行。
保護(hù)(Protect or Access)代理:控制對(duì)象的訪問(wèn),提供不同級(jí)別使用的不同的訪問(wèn)權(quán)限。
Cache代理:為一個(gè)目標(biāo)的結(jié)果提供一個(gè)臨時(shí)的保存空間,以便于多個(gè)客戶端可以使用這些結(jié)果
防火墻(Firewall)代理:保護(hù)目標(biāo)不受惡意侵犯
智能引用(Smart Reference)代理:當(dāng)一個(gè)對(duì)象被調(diào)用引用的時(shí)候,提供一些額外的操作,可以把調(diào)用的次數(shù)或調(diào)用的位置記錄下來(lái)。
二、優(yōu)點(diǎn)
1、增加了中間代理層,降低了客戶端與對(duì)象之間的耦合度
2、中間的代理對(duì)對(duì)象增加了保護(hù)層次,同時(shí)也可以增加一些額外的操作例如權(quán)限控制、智能化
3、職責(zé)清晰明了。抽象—真實(shí)—代理
三、缺點(diǎn)
1、由于增加了代理對(duì)象,有些情況可能會(huì)造成代理之間的請(qǐng)求變慢
2、由于增加了代理對(duì)象,增加了一些額外的工作,造成了系統(tǒng)的復(fù)雜度
總結(jié)
到這里設(shè)計(jì)模式中的結(jié)構(gòu)型的各個(gè)設(shè)計(jì)模式我就介紹完了。最后一個(gè)代理模式,理解起來(lái)也是相對(duì)簡(jiǎn)單的。重點(diǎn)理解代理一詞。再回首、看看我們也將看完了設(shè)計(jì)模式三個(gè)部分中的兩個(gè)部分。創(chuàng)建型——解決對(duì)象創(chuàng)建的問(wèn)題,對(duì)象之間解耦的問(wèn)題。結(jié)構(gòu)型——主要解決的是類和對(duì)象之間的結(jié)構(gòu)問(wèn)題。這里又包括類結(jié)構(gòu)和對(duì)象結(jié)構(gòu)問(wèn)題。這里我們?cè)賮?lái)回顧一下結(jié)構(gòu)型設(shè)計(jì)模式及其重點(diǎn)吧
適配器模式——注重轉(zhuǎn)換接口,使接口匹配、達(dá)到復(fù)用的目的
橋接模式——注重接口和實(shí)現(xiàn)的分離,注重多維度的變化。
裝飾模式——注重穩(wěn)定接口的前提下對(duì)對(duì)象進(jìn)行擴(kuò)展
組合模式——注重將一對(duì)多轉(zhuǎn)換為一對(duì)一,樹型結(jié)構(gòu)層次的關(guān)系
外觀模式——簡(jiǎn)化接口和客戶端之間的調(diào)用依賴關(guān)系
享元模式——注重最小單元對(duì)象的共享
代理模式——增加中間層次實(shí)現(xiàn)控制
?
不要為它的結(jié)束而哭,應(yīng)當(dāng)為它的開始而笑。
C#設(shè)計(jì)模式系列目錄 <https://www.cnblogs.com/hulizhong/p/11394686.html>
歡迎大家掃描下方二維碼,和我一起踏上設(shè)計(jì)模式的闖關(guān)之路吧!
?
熱門工具 換一換
