什麼是享元模式? 所謂享元模式就是運行共用技術有效地支持大量細粒度對象的復用。系統使用少量對象,而且這些都比較相似,狀態變化小,可以實現對象的多次復用。共用模式是支持大量細粒度對象的復用,所以享元模式要求能夠共用的對象必須是細粒度對象。兩個重要的概念:內部狀態、外部狀態。 內部狀態:在享元對象內部不 ...
什麼是享元模式?
所謂享元模式就是運行共用技術有效地支持大量細粒度對象的復用。系統使用少量對象,而且這些都比較相似,狀態變化小,可以實現對象的多次復用。共用模式是支持大量細粒度對象的復用,所以享元模式要求能夠共用的對象必須是細粒度對象。
兩個重要的概念:內部狀態、外部狀態。
- 內部狀態:在享元對象內部不隨外界環境改變而改變的共用部分。
- 外部狀態:隨著環境的改變而改變,不能夠共用的狀態就是外部狀態。
正因為享元模式區分了內部狀態和外部狀態,我們就可以通過設置不同的外部狀態使得相同的對象可以具備一些不同的特性,而內部狀態設置為相同部分。在我們的程式設計過程中,我們可能會需要大量的細粒度對象來表示對象,如果這些對象除了幾個參數不同外其他部分都相同,這個時候我們就可以利用享元模式來大大減少應用程式當中的對象。如何利用享元模式呢?這裡我們只需要將他們少部分的不同的部分當做參數移動到類實例的外部去,然後再方法調用的時候將他們傳遞過來就可以了
具體代碼實現
/// <summary> /// 抽象享元類 /// </summary> public abstract class Flyweight { public abstract void Operation(int extrinsicstate); } /// <summary> /// 具體享元對象 /// </summary> public class ConcreteFlyweight : Flyweight { /// <summary> /// 內部狀態 /// </summary> private string intrinsicstate; /// <summary> /// 構造函數 /// </summary> /// <param name="innerState"></param> public ConcreteFlyweight(string innerState) { this.intrinsicstate = innerState; } /// <summary> /// 操作 /// </summary> /// <param name="extrinsicaste">外部狀態</param> public override void Operation(int extrinsicstate) { Console.WriteLine($"具體實現類: intrinsicstate {intrinsicstate}, extrinsicstate {extrinsicstate}"); } } /// <summary> /// 享元工廠,負責創建和管理享元對象 /// </summary> public class FlyweightFactory { /// <summary> /// 享元對象記憶體緩存 /// </summary> public Dictionary<string, Flyweight> flyweights = new Dictionary<string, Flyweight>(); public FlyweightFactory() { flyweights.Add("A", new ConcreteFlyweight("A")); flyweights.Add("B", new ConcreteFlyweight("B")); flyweights.Add("C", new ConcreteFlyweight("C")); } public Flyweight GetFlyweight(string key) { if (!flyweights.ContainsKey(key)) { Console.WriteLine($"駐留池中不存在字元串{key}"); flyweights.Add(key, new ConcreteFlyweight(key)); } return flyweights[key] as Flyweight; } } /// <summary> /// 客戶端調用 /// </summary> /// <param name="args"></param> static void Main(string[] args) { int externalstate = 10; // 定義外部狀態,如字母的位置等信息 FlyweightFactory factory = new FlyweightFactory(); // 初始化享元工廠 Flyweight fa = factory.GetFlyweight("A"); fa.Operation(--externalstate); Flyweight fb = factory.GetFlyweight("B"); fb.Operation(--externalstate); Flyweight fd = factory.GetFlyweight("D"); fd.Operation(--externalstate); Console.ReadLine(); }
輸出
具體實現類: intrinsicstate A, extrinsicstate 9
具體實現類: intrinsicstate B, extrinsicstate 8
駐留池中不存在字元串D
具體實現類: intrinsicstate D, extrinsicstate 7
享元模式的優缺點
優點: 降低了系統中對象的數量,從而降低了系統中細粒度對象給記憶體帶來的壓力。
缺點: 為了使對象可以共用,需要將一些狀態外部化,這使得程式的邏輯更複雜,使系統複雜化。
享元模式的應用場景
在下麵所有條件都滿足時,可以考慮使用享元模式:
- 一個系統中有大量的對象;
- 這些對象耗費大量的記憶體;
- 這些對象中的狀態大部分都可以被外部化
- 這些對象可以按照內部狀態分成很多的組,當把外部對象從對象中剔除時,每一個組都可以僅用一個對象代替
- 軟體系統不依賴這些對象的身份,
.NET中,String類的實現用到了享元模式,可以參考字元串駐留池的相關介紹。