熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> .NET編程 >> 正文

老生常談:享元模式

2013-11-13 10:03:43  來源: .NET編程 
    享元模式
    以共享的方式高效地支持大量的細粒度對象
    享元對象的狀態
    :內蘊狀態(Internal State)內蘊狀態存儲在享元對象內部且不會隨環境改變而改變因此內蘊狀態並可以共享
    :外蘊狀態(External State)外蘊狀態是隨環境改變而改變的不可以共享的狀態享元對象的外蘊狀態必須由客戶端保存並在享元對象被創建之後在需要使用的時候再傳入到享元對象內部外蘊狀態與內蘊狀態是相互獨立的
    享元模式的應用條件
    : 一個系統有大量的對象
    :這些對象耗費大量的內存
    :這些對象的狀態中的大部分都可以外部化
    :這些對象可以按照內蘊狀態分成很多的組當把外蘊對象從對象中剔除時每一個組都可以僅用一個對象代替
    :軟件系統不依賴於這些對象的身份換言之這些對象可以是不可分辨的
    NET的享元模式
    NET中的String類型就是運用了享元模式……NET中如果第一次創建了一個字符串對象s下次再創建相同的字符串s時只是把它的引用指向s所引用的具體對象這就實現了相同字符串在內存中的共享下面的程序來演示s和s的引
    用是否一致 輸出的結果為True
    string s = 測試字符串一;
    string s = 測試字符串一;
    ConsoleWriteLine(ObjectReferenceEquals(s s))
    注意如果再有一個字符串s它的初始值為測試字符串再對它進行操作s = s + 這時雖然s和s的值相同但是它們的引用是不同的
    享元模式的分類
    單純享元模式
    復合享元模式
    第一單純享元模式
    單純享元模式結構圖
    單純享元模式構成說明
    >:抽象享元(Flyweight)角色此角色是所有的具體享元類的超類為這些類規定出需要實現的公共接口那些需要外蘊狀態(External State)的操作可以通過調用商業方法以參數形式傳入
    /// <summary>
    /// Flyweight
    /// </summary>
    abstract class Flyweight
    {
    // Methods
    /// <summary>
    /// 抽象享元對象的商業方法
    /// </summary>
    /// <param name=extrinsicstate>外蘊狀態</param>
    abstract public void Operation(int extrinsicstate)
    }
    >:具體享元(ConcreteFlyweight)角色實現抽象享元角色所規定的接口如果有內蘊狀態的話必須負責為內蘊狀態提供存儲空間享元對象的內蘊狀態必須與對象所處的周圍環境無關從而使得享元對象可以在系統內共享的
    /// <summary>
    /// ConcreteFlyweight
    /// </summary>
    class ConcreteFlyweight : Flyweight
    {
    private string intrinsicstate = A;
    // Methods
    override public void Operation(int extrinsicstate)
    {
    ConsoleWriteLine(ConcreteFlyweight: intrinsicstate {} extrinsicstate {}
    intrinsicstate extrinsicstate)
    }
    }
    >:享元工廠(FlyweightFactory)角色本角色負責創建和管理享元角色本角色必須保證享元對象可以被系統適當地共享當一個客戶端對象調用一個享元對象的時候享元工廠角色會檢查系統中是否已經有一個復合要求的享元對象如果已經有了享元工廠角色就應當提供這個已有的享元對象如果系統中沒有一個適當的享元對象的話享元工廠角色就應當創建一個合適的享元對象


    注意客戶端不可以直接實例化享元類必須通過享元工廠類來創建因為享元工廠類在系統中只能有一個所以可以結合單例模式來改善當客戶端需要單純享元對象時需要調用享元工廠的Singleton()方法此時工廠會取得所有的單純享元對象然後傳入所需的單純享元對象的內蘊狀態工廠方法負責產生所需要的享元對象
    /// <summary>
    /// FlyweightFactory
    /// </summary>
    class FlyweightFactory
    {
    // Fields
    private Dictionary<string Flyweight> flyweights = new Dictionary<string Flyweight>()
    private static readonly FlyweightFactory instance = new FlyweightFactory()
    /// <summary>
    /// Constructors
    /// </summary>
    private  FlyweightFactory()
    {
    }
    // Methods
    /// <summary>
    /// 從享元工廠中生產出一個具體的享元對象
    /// </summary>
    /// <param name=key>內蘊狀態</param>
    /// <returns></returns>
    public Flyweight GetFlyweight(string key)
    {
    return ((Flyweight)flyweights[key])
    }
    /// <summary>
    /// 享元工廠單例方法
    /// </summary>
    /// <returns></returns>
    public static  FlyweightFactory Singleton()
    {
    return FlyweightFactoryinstance;
    }
    /// <summary>
    /// 向享元工廠對象增加一個享元對象
    /// </summary>
    /// <param name=sKey>內蘊狀態</param>
    /// <param name=_Flyweight>具體享元對象</param>
    public void AddFlyweight(string sKey Flyweight _Flyweight)
    {
    flyweightsAdd(sKey _Flyweight)
    }
    public Flyweight factory(string sKey)
    {
    if (flyweightsContainsKey(sKey))
    {
    return thisGetFlyweight(sKey)
    }
    else
    {
    thisAddFlyweight(sKey new ConcreteFlyweight())
    return thisGetFlyweight(sKey)
    }
    }
    }
    >:客戶端(Client)角色需要維護一個對所有享元對象的引用需要自行存儲所有享元對象外蘊狀態
    // 初始化外蘊狀態值
    int extrinsicstate = ;
    //享元工廠對象使用單例
    FlyweightFactory f = FlyweightFactorySingleton () ;
    //調用過程
    //向享元工廠對象請求一個內蘊狀態為X的單純享元對象
    Flyweight fx = ffactory(X
    //調用X的商業方法X的外蘊狀態值為
    fxOperation(extrinsicstate)
    Flyweight fy = ffactory(Y
    fyOperation(extrinsicstate)
    Flyweight fz = ffactory(Z
    fzOperation(extrinsicstate)
    第二復合享元模式
    復合享元模式結構圖
    結構對象說明
    :抽象享元角色此角色是所有的具體享元類的超類為這些類規定出需要實現的公共接口那些需要外蘊狀態(External State)的操作可以通過方法的參數傳入抽象享元的接口使得享元變得可能但是並不強制子類實行共享因此並非所有的享元對象都是可以共享的
    :具體享元(ConcreteFlyweight)角色實現抽象享元角色所規定的接口如果有內蘊狀態的話必須負責為內蘊狀態提供存儲空間享元對象的內蘊狀態必須與對象所處的周圍環境無關從而使得享元對象可以在系統內共享有時候具體享元角色又叫做單純具體享元角色因為復合享元角色是由單純具體享元角色通過復合而成的
    :復合享元(UnsharableFlyweight)角色復合享元角色所代表的對象是不可以共享的但是一個復合享元對象可以分解成為多個本身是單純享元對象的組合復合享元角色又稱做不可共享的享元對象
    :享元工廠(FlyweightFactoiy)角色本角色負責創建和管理享元角色本角色必須保證享元對象可以被系統適當地共享當一個客戶端對象請求一個享元對象的時候享元工廠角色需要檢查系統中是否已經有一個符合要求的享元對象如果已經有了享元工廠角色就應當提供這個已有的享元對象如果系統中沒有一個適當的享元對象的話享元工廠角色就應當創建一個新的合適的享元對象
    :客戶端(Client)角色本角色還需要自行存儲所有享元對象的外蘊狀態
    享元模式的優點
    大幅度地降低內存中對象的數量
    享元模式的缺點
    :享元模式使得系統更加復雜為了使對象可以共享需要將一些狀態外部化這使得程序的邏輯復雜化
    :享元模式將享元對象的狀態外部化而讀取外部狀態使得運行時間稍微變長
    總結
    享元模式一般是解決系統性能問題的所以經常用於底層開發在項目開發中並不常用


From:http://tw.wingwit.com/Article/program/net/201311/12438.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.