代理模式(Proxy):
代理模式就是給某一個物件提供一個代理,并由代理物件控制對原有物件的參考,在一些情況下,一個客戶不想或者不能直接參考一個物件,而代理物件可以在客戶端和目標物件之間起到中介的作用,例如windows桌面端的快捷方式就是一個代理,
代理模式按照使用目的可以分為:
1)遠程代理:為一個位于不同的地址空間的物件提供一個局域代表物件,這個不同的地址空間可以是本電腦中,也可以在另一臺電腦中,如客戶端呼叫web服務或wcf服務,
2)虛擬代理:根據需要創建一個資源消耗較大的物件,使得物件只在需要時才會被真正創建,
3)Copy-on-Write代理:虛擬代理的一種,把復制(或克隆)拖延到只有在客戶端需要時,才真正采取行動,
4)保護(Protected or Access)代理:控制一個物件的訪問,可以給不同的用戶提供不同級別的使用權限,
5)Cache代理:為某一個目標操作的結果提供臨時的存盤空間,以便多個客戶端可以操作這些結果,
6)防火墻(FireWall)代理:保護目標不讓惡意用戶接近,
7)同步化(Synchronization)代理
8)智能參考(Smart Reference)代理:當一個物件被參考時,提供一些額外的操作,比如將對此物件呼叫的次數記錄下來,
接下來以一個需求案例來說明下代理模式:
現有收費商務資訊查詢系統的二次開發,增加需求:
1)添加用戶身份驗證;2)添加日志記錄;3)要求以松耦合的方式進行功能添加
1 internal class Program 2 { 3 private static void Main(string[] args) 4 { 5 /* 6 * <?xml version="1.0" encoding="utf-8" ?> 7 * <configuration> 8 * <appSettings> 9 * <add key="proxy" value="https://www.cnblogs.com/az4215/p/Proxy,Proxy.ProxySearcher" /> 10 * </appSettings> 11 * </configuration> 12 */ 13 var proxy = ConfigurationManager.AppSettings["proxy"].Split(","); 14 var searcher = (Searcher)Assembly.Load(proxy[0]).CreateInstance(proxy[1]); 15 var result = searcher.DoSearch("楊過", "玉女心經"); 16 } 17 } 18 19 /// <summary> 20 /// (1) AccessValidator:身份驗證類,業務類,它提供方法Validate()來實作身份驗證, 21 /// </summary> 22 internal class AccessValidator 23 { 24 //模擬實作登錄驗證 25 public bool Validate(string userId) 26 { 27 Console.WriteLine($"在資料庫中驗證用戶{userId}是否是合法用戶?"); 28 if (userId.Equals("楊過")) 29 { 30 Console.WriteLine("'{0}'登錄成功!", userId); 31 return true; 32 } 33 else 34 { 35 Console.WriteLine("'{0}'登錄失敗!", userId); 36 return false; 37 } 38 } 39 } 40 41 /// <summary> 42 /// (2) Logger:日志記錄類,業務類,它提供方法Log()來保存日志, 43 /// </summary> 44 internal class Logger 45 { 46 //模擬實作日志記錄 47 public void Log(string userId) 48 { 49 Console.WriteLine($"更新資料庫,用戶{userId}查詢次數加1!"); 50 } 51 } 52 53 /// <summary> 54 /// (3) Searcher:抽象查詢類,充當抽象主題角色,它宣告了DoSearch()方法, 55 /// </summary> 56 internal interface Searcher 57 { 58 string DoSearch(string userId, string keyWord); 59 } 60 61 /// <summary> 62 /// (4) RealSearcher:具體查詢類,充當真實主題角色,它實作查詢功能,提供方法DoSearch()來查詢資訊, 63 /// </summary> 64 internal class RealSearcher : Searcher 65 { 66 public string DoSearch(string userId, string keyWord) 67 { 68 Console.WriteLine($"用戶{userId}使用關鍵詞{keyWord}查詢商務資訊!"); 69 return "回傳具體內容"; 70 } 71 } 72 73 /// <summary> 74 /// (5) ProxySearcher:代理查詢類,充當代理主題角色,它是查詢代理,維持了對RealSearcher物件、AccessValidator物件和Logger物件的參考, 75 /// </summary> 76 internal class ProxySearcher : Searcher 77 { 78 private Searcher searcher; 79 private AccessValidator validator; 80 private Logger logger; 81 82 public ProxySearcher() 83 { 84 searcher = new RealSearcher(); 85 } 86 87 public string DoSearch(string userId, string keyword) 88 { 89 //如果身份驗證成功,則執行查詢 90 if (this.Validate(userId)) 91 { 92 string result = searcher.DoSearch(userId, keyword); //呼叫真實主題物件的查詢方法 93 this.Log(userId); //記錄查詢日志 94 return result; //回傳查詢結果 95 } 96 else 97 { 98 return null; 99 }100 }101 102 //創建訪問驗證物件并呼叫其Validate()方法實作身份驗證103 public bool Validate(string userId)104 {105 validator = new AccessValidator();106 return validator.Validate(userId);107 }108 109 //創建日志記錄物件并呼叫其Log()方法實作日志記錄110 public void Log(string userId)111 {112 logger = new Logger();113 logger.Log(userId);114 }115 }
代理模式角色分四種:
1)主題介面(Searcher):定義代理類和真實主題的公共對外方法,也是代理類代理真實主題的方法;
2)真實主題(RealSeracher):真正實作業務邏輯的類;
3)代理類(ProxySeracher):用來代理和封裝真實主題;
4)客戶端:使用代理類和主題完成作業,
代理模式的優缺點:
優點:
1)代理模式能夠將呼叫用于真正被呼叫的物件隔離,在一定程度上降低了系統的耦合度;
2)代理物件在客戶端和目標物件之間起到一個中介的作用,這樣可以起到對目標物件的保護,代理物件可以在對目標物件發出請求之前進行一個額外的操作,例如權限檢查等,
缺點:
1)由于在客戶端和真實主題之間增加了一個代理物件,所以會造成請求的處理速度變慢;
2)實作代理類也需要額外的作業,從而增加了系統的實作復雜度,
代理模式與配接器模式的區別?
學習完配接器模式和代理模式之后,會產生這樣的疑問:貌似兩種模式差不多?兩者都是定義了一個目標物件(抽象物件),客戶端依賴該抽象物件完成相應功能,這么一解釋好像是一樣的,那為什么大牛們會分成兩種模式呢?配接器模式是因為新舊介面不一致導致出現了客戶端無法得到滿足的問題,但由于舊的介面是不能被完全重構掉的,因為我們還想使用實作了這個介面的一些服務,那么為了使用以前實作舊介面的服務,我們就應該把新的介面轉換成舊介面;實作這個轉換的類就是抽象意義的轉換器,相比于配接器的應用場景,代理就不一樣了,雖然代理也同樣是增加了一層,但是,代理提供的介面和原本的介面是一樣的,代理模式的作用是不把實作直接暴露給客戶端,而是通過代理這個層,代理能夠做一些處理,
代理模式與委托的區別?
1)代理是模式提供一種"一個類對另外一個類的控制權"是類與類之間關系;委托提供了"一種方法的執行會同時執行加載在上面的方法"是方法與方法之間的關系,
2)委托可以代替代理,但是代理不能代替委托,
3)委托可以動態加載方法,代理不能實作,
4)委托物件所加載的方法不一定要屬于同一個類,但是代理的類必須屬于同一個類,
參考:https://blog.csdn.net/lovelion/article/details/8228042
https://www.cnblogs.com/zhili/p/ProxyPattern.html
https://www.cnblogs.com/chenwolong/p/Proxy.html
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/44338.html
標籤:設計模式
上一篇:單例模式
下一篇:觀察者模式
