一、前言 面向對象技術可以很好地解決一些靈活性或可擴展性問題,但在很多情況下需要在系統中增加類和對象的個數。當對象數量太多時,將導致運行代價過高,帶來性能下降等問題。 享元模式正是為解決這一類問題而誕生的。享元模式通過共用技術實現相同或相似對象的重用。 在享元模式中通常會出現工廠模式,需要創建一個享 ...
一、前言
面向對象技術可以很好地解決一些靈活性或可擴展性問題,但在很多情況下需要在系統中增加類和對象的個數。當對象數量太多時,將導致運行代價過高,帶來性能下降等問題。
享元模式正是為解決這一類問題而誕生的。享元模式通過共用技術實現相同或相似對象的重用。
在享元模式中通常會出現工廠模式,需要創建一個享元工廠來負責維護一個享元池用於存儲具有相同內部狀態的享元對象。
在享元模式中共用的是享元對象的內部狀態,外部狀態需要通過環境來設置。在實際使用中,能夠共用的內部狀態是有限的,因此享元對象一般都設計為較小的對象,它所包含的內部狀態較少,這種對象也稱為細粒度對象。享元模式的目的就是使用共用技術來實現大量細粒度對象的復用。
二、基本概念
享元模式(Flyweight Pattern):運用共用技術有效地支持大量細粒度對象的復用。系統只使用少量的對象,而這些對象都很相似,狀態變化很小,可以實現對象的多次復用。由於享元模式要求能夠共用的對象必須是細粒度對象,因此它又稱為輕量級模式,它是一種對象結構型模式。
享元模式(Flyweight Pattern)主要用於減少創建對象的數量,以減少記憶體占用和提高性能。這種類型的設計模式屬於結構型模式,它提供了減少對象數量從而改善應用所需的對象結構的方式。
享元模式四個基本角色:
抽象享元角色(Flyweight):為具體享元角色規定了必須實現的方法,而外蘊狀態就是以參數的形式通過此方法傳入。
具體享元角色(ConcreteFlyweight):實現抽象角色規定的方法。如果存在內蘊狀態,就負責為內蘊狀態提供存儲空間。
享元工廠角色(FlyweightFactory):負責創建和管理享元角色。要想達到共用的目的,這個角色的實現是關鍵。
非共用具體享元角色(UnsharedConcreteFlyweight):不需要共用的Flyweight子類。
下麵就四個基本角色代碼說明
三、基本代碼實例
基本代碼實現:
static void Main(string[] args) { int extrinsicstate = 10; FlyweightFactory factory = new FlyweightFactory(); Flyweight fx = factory.GetFlyweight("X"); fx.Method(--extrinsicstate); Flyweight fy = factory.GetFlyweight("Y"); fy.Method(--extrinsicstate); Flyweight fz = factory.GetFlyweight("Z"); fz.Method(--extrinsicstate); UnsharedConcreteFlyweight uf=new UnsharedConcreteFlyweight(); uf.Method(--extrinsicstate); Console.WriteLine(factory.GetFlyWeightsCount()); Console.ReadKey(); } // 抽象享元類 public abstract class Flyweight { public abstract void Method(int extrinsicstate); } //具體享元類 public class ConcreteFlyweight : Flyweight { public override void Method(int extrinsicstate) { Console.WriteLine("具體享元類" + extrinsicstate); } } //非共用具體享元類 public class UnsharedConcreteFlyweight : Flyweight { public override void Method(int extrinsicstate) { Console.WriteLine("非共用具體享元類" + extrinsicstate); } } //享元工廠類 public class FlyweightFactory { private Hashtable flyweights = new Hashtable(); //初始化工廠時模式生成三個實例 public FlyweightFactory() { flyweights.Add("X", new ConcreteFlyweight()); flyweights.Add("Y", new ConcreteFlyweight()); flyweights.Add("Z", new ConcreteFlyweight()); } //根據客戶端要求,返回對應的實例 public Flyweight GetFlyweight(string str) { return flyweights[str] as Flyweight; } //獲取flyweights實例個數 public int GetFlyWeightsCount() { return flyweights.Count; } }
運行結果:
四、總結
優點:
大大減少對象的創建,降低系統的記憶體,使效率提高。
缺點:
提高了系統的負責度,需要分離出外部狀態和內部狀態,而且外部狀態具有固有化的性質,不應該隨著內部狀態的變化而變化,否則會造成系統的混亂。
何時使用:
1、系統中有大量對象。
2、這些對象消耗大量記憶體。
3、這些對象的狀態大部分可以外部化。
4、這些對象可以按照內蘊狀態分為很多組,當把外蘊對象從對象中剔除出來時,每一組對象都可以用一個對象來代替。
5、系統不依賴於這些對象身份,這些對象是不可分辨的。
應用實例:
1、JAVA 中的 String,如果有則返回,如果沒有則創建一個字元串保存在字元串緩存池裡面。
2、資料庫的數據池。
代碼下載:
https://yunpan.cn/cqKQnQLEhithe (提取碼:a667)