今天我們來講一下享元模式。 我們在工作之餘可能會接一些私活,比如,幫人開發一個網站,幫人開發一個私人博客。隨著私活的增多,會發現,有很多項目是有相同之處的,比如,幫人開發一個網站,你會發現,之前做的一些網站的代碼單元是可以公共的。所以,即便是有很多的私活,我們不要盲目的去做一些項目,我們要善於發現, ...
今天我們來講一下享元模式。
我們在工作之餘可能會接一些私活,比如,幫人開發一個網站,幫人開發一個私人博客。隨著私活的增多,會發現,有很多項目是有相同之處的,比如,幫人開發一個網站,你會發現,之前做的一些網站的代碼單元是可以公共的。所以,即便是有很多的私活,我們不要盲目的去做一些項目,我們要善於發現,善於總結,這樣會大大提高我們的效率。
我們將上述場景用代碼體現一下就如同下麵代碼:
1 /// <summary> 2 /// 網站類 3 /// </summary> 4 class WebSite 5 { 6 private string name = ""; 7 8 public WebSite(string name) 9 { 10 this.name = name; 11 } 12 13 public void Use() 14 { 15 Console.WriteLine($"網站分類:{name}"); 16 } 17 }
客戶端調用:
1 public static void Main() 2 { 3 WebSite fx = new WebSite("門戶網站"); 4 fx.Use(); 5 6 WebSite fy = new WebSite("門戶網站"); 7 fy.Use(); 8 9 WebSite fz = new WebSite("門戶網站"); 10 fz.Use(); 11 12 WebSite fl = new WebSite("個人博客"); 13 fl.Use(); 14 15 WebSite fm = new WebSite("個人博客"); 16 fm.Use(); 17 18 WebSite fn = new WebSite("個人博客"); 19 fn.Use(); 20 21 Console.ReadKey(); 22 }
在弄清楚如何共用代碼之前,我們先來談一下今天我們要講的設計模式——享元模式。
享元模式,運用共用技術有效地支持大量細粒度地對象,所有具體享元類地超類或介面,通過這個介面,可以接受並作用於外部狀態。
我們再來看一下它的結構代碼:
1 //所有具體享元類地超類或介面,通過這個介面,可以接受並作用於外部狀態 2 abstract class Flyweight 3 { 4 public abstract void Operation(int extrinsicstate); 5 } 6 //繼承Flyweight實現Flyweight介面 7 class ConcreteFlyweight : Flyweight 8 { 9 public override void Operation(int extrinsicstate) 10 { 11 Console.WriteLine($"具體Flyweight:{extrinsicstate}"); 12 } 13 } 14 //不需要共用Flyweight子類,因為Flyweight介面共用成為可能,但它並不強制共用 15 class UnsharedConcreteFlyweight : Flyweight 16 { 17 public override void Operation(int extrinsicstate) 18 { 19 Console.WriteLine($"不共用的具體Flyweight:{extrinsicstate}"); 20 } 21 } 22 //享元工廠,用來創建並管理Flyweight對象,它主要是用來確保合理的 23 //共用Flyweight,當用戶請求一個Flyweight時,享元工廠對象提供一個 24 //已經創建的實例或者創建一個(如果不存在的話) 25 class FlyweighFactory 26 { 27 private Hashtable flyweights = new Hashtable(); 28 /// <summary> 29 /// 初始化工廠時,先生成三個實例 30 /// </summary> 31 public FlyweighFactory() 32 { 33 flyweights.Add("X", new ConcreteFlyweight()); 34 flyweights.Add("Y", new ConcreteFlyweight()); 35 flyweights.Add("Z", new ConcreteFlyweight()); 36 } 37 //根據客戶端請求,獲得已生成的實例 38 public Flyweight GetFlyweight(string key) 39 { 40 return ((Flyweight) flyweights[key]); 41 } 42 }
客戶端:
1 public static void Main() 2 { 3 //代碼外部狀態 4 int extrinsicstate = 22; 5 FlyweighFactory f = new FlyweighFactory(); 6 7 Flyweight fx = f.GetFlyweight("X"); 8 fx.Operation(--extrinsicstate); 9 10 Flyweight fy = f.GetFlyweight("Y"); 11 fy.Operation(--extrinsicstate); 12 13 Flyweight fz = f.GetFlyweight("Z"); 14 fz.Operation(--extrinsicstate); 15 16 UnsharedConcreteFlyweight uf = new UnsharedConcreteFlyweight(); 17 18 uf.Operation(--extrinsicstate); 19 20 Console.ReadKey(); 21 }
好,我們用享元模式將我們案例中的代碼來重構一下:
1 //網站抽象類 2 abstract class WebSite 3 { 4 public abstract void Use(); 5 } 6 //具體網站類 7 class ConcreteWebSite : WebSite 8 { 9 private string name = ""; 10 11 public ConcreteWebSite(string name) 12 { 13 this.name = name; 14 } 15 public override void Use() 16 { 17 Console.WriteLine($"網站分類{name}"); 18 } 19 } 20 //網站工廠 21 class WebSiteFactory 22 { 23 private Hashtable flyweights = new Hashtable(); 24 25 public WebSite GetWebSiteCategory(string key) 26 { 27 //判斷是否存在這個對象,如果存在,則直接返回,否則實例化它再返回 28 if (!flyweights.ContainsKey(key)) 29 { 30 flyweights.Add(key, new ConcreteWebSite(key)); 31 return (WebSite)flyweights[key]; 32 } 33 else 34 { 35 return (WebSite)flyweights[key]; 36 } 37 } 38 //獲得網站分類總數 39 public int GetWebSiteCount() 40 { 41 return flyweights.Count; 42 } 43 }
客戶端:
1 public static void Main() 2 { 3 WebSiteFactory f = new WebSiteFactory(); 4 5 //實例化 門戶網站 對象 6 WebSite fx = f.GetWebSiteCategory("門戶網站"); 7 fx.Use(); 8 9 //共用上方生成的對象,不再實例化 10 WebSite fy = f.GetWebSiteCategory("門戶網站"); 11 fy.Use(); 12 //共用上方生成的對象,不再實例化 13 WebSite fz = f.GetWebSiteCategory("門戶網站"); 14 fz.Use(); 15 16 WebSite fl = f.GetWebSiteCategory("個人博客"); 17 fl.Use(); 18 19 WebSite fm = f.GetWebSiteCategory("個人博客"); 20 fm.Use(); 21 22 WebSite fn = f.GetWebSiteCategory("個人博客"); 23 fn.Use(); 24 25 //統計實例化個數,結果應該為2 26 Console.WriteLine($"網站分類總數為{f.GetWebSiteCount()}"); 27 Console.ReadKey(); 28 }
這樣寫基本體現了享元模式享元模式,但是我們在做項目的過程中,即便是再相似的項目,面對不同企業,也會有不同的地方。
好,今天的享元模式就講到這裡了,下一篇我們講 解釋器模式
本系列將持續更新,喜歡的小伙伴可以點一下關註和推薦,謝謝大家的支持