<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    無為

    無為則可為,無為則至深!

      BlogJava :: 首頁 :: 聯(lián)系 :: 聚合  :: 管理
      190 Posts :: 291 Stories :: 258 Comments :: 0 Trackbacks

    一、 享元(Flyweight)模式(轉(zhuǎn)貼)

    Flyweight在拳擊比賽中指最輕量級,即"蠅量級",有些作者翻譯為"羽量級"。這里使用"享元模式"更能反映模式的用意。

    享元模式以共享的方式高效地支持大量的細粒度對象。享元對象能做到共享的關(guān)鍵是區(qū)分內(nèi)蘊狀態(tài)(Internal State)和外蘊狀態(tài)(External State)。內(nèi)蘊狀態(tài)是存儲在享元對象內(nèi)部并且不會隨環(huán)境改變而改變。因此內(nèi)蘊狀態(tài)并可以共享。

    外蘊狀態(tài)是隨環(huán)境改變而改變的、不可以共享的狀態(tài)。享元對象的外蘊狀態(tài)必須由客戶端保存,并在享元對象被創(chuàng)建之后,在需要使用的時候再傳入到享元對象內(nèi)部。外蘊狀態(tài)與內(nèi)蘊狀態(tài)是相互獨立的。

    享元模式的應(yīng)用

    享元模式在編輯器系統(tǒng)中大量使用。一個文本編輯器往往會提供很多種字體,而通常的做法就是將每一個字母做成一個享元對象。享元對象的內(nèi)蘊狀態(tài)就是這個字母,而字母在文本中的位置和字模風(fēng)格等其他信息則是外蘊狀態(tài)。比如,字母a可能出現(xiàn)在文本的很多地方,雖然這些字母a的位置和字模風(fēng)格不同,但是所有這些地方使用的都是同一個字母對象。這樣一來,字母對象就可以在整個系統(tǒng)中共享。


    二、 單純享元模式的結(jié)構(gòu)

    在單純享元模式中,所有的享元對象都是可以共享的。單純享元模式所涉及的角色如下:

    抽象享元(Flyweight)角色:此角色是所有的具體享元類的超類,為這些類規(guī)定出需要實現(xiàn)的公共接口。那些需要外蘊狀態(tài)(External State)的操作可以通過調(diào)用商業(yè)方法以參數(shù)形式傳入。

    具體享元(ConcreteFlyweight)角色:實現(xiàn)抽象享元角色所規(guī)定的接口。如果有內(nèi)蘊狀態(tài)的話,必須負責(zé)為內(nèi)蘊狀態(tài)提供存儲空間。享元對象的內(nèi)蘊狀態(tài)必須與對象所處的周圍環(huán)境無關(guān),從而使得享元對象可以在系統(tǒng)內(nèi)共享的。

    享元工廠(FlyweightFactory)角色:本角色負責(zé)創(chuàng)建和管理享元角色。本角色必須保證享元對象可以被系統(tǒng)適當(dāng)?shù)毓蚕怼.?dāng)一個客戶端對象調(diào)用一個享元對象的時候,享元工廠角色會檢查系統(tǒng)中是否已經(jīng)有一個復(fù)合要求的享元對象。如果已經(jīng)有了,享元工廠角色就應(yīng)當(dāng)提供這個已有的享元對象;如果系統(tǒng)中沒有一個適當(dāng)?shù)南碓獙ο蟮脑挘碓S角色就應(yīng)當(dāng)創(chuàng)建一個合適的享元對象。

    客戶端(Client)角色:本角色需要維護一個對所有享元對象的引用。本角色需要自行存儲所有享元對象的外蘊狀態(tài)。


    三、 單純享元模式的示意性源代碼

    // Flyweight pattern -- Structural example  
    using System;
    using System.Collections;

    // "FlyweightFactory"
    class FlyweightFactory
    {
      
    // Fields
      private Hashtable flyweights = new Hashtable();

      
    // Constructors
      public FlyweightFactory()
      
    {
        flyweights.Add(
    "X"new ConcreteFlyweight());
        flyweights.Add(
    "Y"new ConcreteFlyweight());
        flyweights.Add(
    "Z"new ConcreteFlyweight());
      }


      
    // Methods
      public Flyweight GetFlyweight(string key)
      
    {
        
    return((Flyweight)flyweights[ key ]);
      }

    }


    // "Flyweight"
    abstract class Flyweight
    {
      
    // Methods
      abstract public void Operation( int extrinsicstate );
    }


    // "ConcreteFlyweight"
    class ConcreteFlyweight : Flyweight
    {
      
    private string intrinsicstate = "A";
      
    // Methods
      override public void Operation( int extrinsicstate )
      
    {
        Console.WriteLine(
    "ConcreteFlyweight: intrinsicstate {0}, extrinsicstate {1}"
          intrinsicstate, extrinsicstate );
      }

    }


    /// <summary>
    /// Client test
    /// </summary>

    public class Client
    {
      
    public static void Main( string[] args )
      
    {
        
    // Arbitrary extrisic state
        int extrinsicstate = 22;
         
        FlyweightFactory f 
    = new FlyweightFactory();

        
    // Work with different flyweight instances
        Flyweight fx = f.GetFlyweight("X");
        fx.Operation( 
    --extrinsicstate );

        Flyweight fy 
    = f.GetFlyweight("Y");
        fy.Operation( 
    --extrinsicstate );

        Flyweight fz 
    = f.GetFlyweight("Z");
        fz.Operation( 
    --extrinsicstate );
      }

    }


    四、 復(fù)合享元模式的結(jié)構(gòu)

    單純享元模式中,所有的享元對象都可以直接共享。下面考慮一個較為復(fù)雜的情況,即將一些單純享元使用合成模式加以復(fù)合,形成復(fù)合享元對象。這樣的復(fù)合享元對象本身不能共享,但是它們可以分解成單純享元對象,而后者則可以共享。

    復(fù)合享元模式的類圖如下圖所示:

    享元模式所涉及的角色有抽象享元角色、具體享元角色、復(fù)合享元角色、享員工廠角色,以及客戶端角色等。

    抽象享元角色:此角色是所有的具體享元類的超類,為這些類規(guī)定出需要實現(xiàn)的公共接口。那些需要外蘊狀態(tài)(External State)的操作可以通過方法的參數(shù)傳入。抽象享元的接口使得享元變得可能,但是并不強制子類實行共享,因此并非所有的享元對象都是可以共享的。

    具體享元(ConcreteFlyweight)角色:實現(xiàn)抽象享元角色所規(guī)定的接口。如果有內(nèi)蘊狀態(tài)的話,必須負責(zé)為內(nèi)蘊狀態(tài)提供存儲空間。享元對象的內(nèi)蘊狀態(tài)必須與對象所處的周圍環(huán)境無關(guān),從而使得享元對象可以在系統(tǒng)內(nèi)共享。有時候具體享元角色又叫做單純具體享元角色,因為復(fù)合享元角色是由單純具體享元角色通過復(fù)合而成的。

    復(fù)合享元(UnsharableFlyweight)角色:復(fù)合享元角色所代表的對象是不可以共享的,但是一個復(fù)合享元對象可以分解成為多個本身是單純享元對象的組合。復(fù)合享元角色又稱做不可共享的享元對象。

    享元工廠(FlyweightFactoiy)角色:本角色負責(zé)創(chuàng)建和管理享元角色。本角色必須保證享元對象可以被系統(tǒng)適當(dāng)?shù)毓蚕怼.?dāng)一個客戶端對象請求一個享元對象的時候,享元工廠角色需要檢查系統(tǒng)中是否已經(jīng)有一個符合要求的享元對象,如果已經(jīng)有了,享元工廠角色就應(yīng)當(dāng)提供這個已有的享元對象;如果系統(tǒng)中沒有一個適當(dāng)?shù)南碓獙ο蟮脑挘碓S角色就應(yīng)當(dāng)創(chuàng)建一個新的合適的享元對象。

    客戶端(Client)角色:本角色還需要自行存儲所有享元對象的外蘊狀態(tài)。

    注:由于復(fù)合享元模式比較復(fù)雜,這里就不再給出示意性代碼。通過將享元模式與合成模式組合在一起,可以確保復(fù)合享元中所包含的每個單純享元都具有相同的外蘊狀態(tài),而這些單純享元的內(nèi)蘊狀態(tài)往往不同。該部分內(nèi)容可以參考《Java與模式》第31章內(nèi)容。


    五、 一個咖啡攤的例子

    在這個咖啡攤(Coffee Stall)所使用的系統(tǒng)里,有一系列的咖啡"風(fēng)味(Flavor)"。客人到攤位上購買咖啡,所有的咖啡均放在臺子上,客人自己拿到咖啡后就離開攤位。咖啡有內(nèi)蘊狀態(tài),也就是咖啡的風(fēng)味;咖啡沒有環(huán)境因素,也就是說沒有外蘊狀態(tài)。如果系統(tǒng)為每一杯咖啡都創(chuàng)建一個獨立的對象的話,那么就需要創(chuàng)建出很多的細小對象來。這樣就不如把咖啡按照種類(即"風(fēng)味")劃分,每一種風(fēng)味的咖啡只創(chuàng)建一個對象,并實行共享。

    使用咖啡攤主的語言來講,所有的咖啡都可按"風(fēng)味"劃分成如Capucino、Espresso等,每一種風(fēng)味的咖啡不論賣出多少杯,都是全同、不可分辨的。所謂共享,就是咖啡風(fēng)味的共享,制造方法的共享等。因此,享元模式對咖啡攤來說,就意味著不需要為每一份單獨調(diào)制。攤主可以在需要時,一次性地調(diào)制出足夠一天出售的某一種風(fēng)味的咖啡。

    很顯然,這里適合使用單純享元模式。系統(tǒng)的設(shè)計如下:

    using System;
    using System.Collections;

    public abstract class Order
    {
      
    // 將咖啡賣給客人
      public abstract void Serve();
      
    // 返回咖啡的名字
      public abstract string GetFlavor();
    }


    public class Flavor : Order
    {
      
    private string flavor;

      
    // 構(gòu)造函數(shù),內(nèi)蘊狀態(tài)以參數(shù)方式傳入
      public Flavor(string flavor)
      
    {
        
    this.flavor = flavor;
      }


      
    // 返回咖啡的名字
      public override string GetFlavor()
      
    {
        
    return this.flavor;
      }


      
    // 將咖啡賣給客人
      public override void Serve()
      
    {
        Console.WriteLine(
    "Serving flavor " + flavor);
      }

    }


    public class FlavorFactory
    {
      
    private Hashtable flavors = new Hashtable();

      
    public Order GetOrder(string key)
      
    {
        
    if(! flavors.ContainsKey(key))
          flavors.Add(key, 
    new Flavor(key));

            
    return ((Order)flavors[key]);
      }


      
    public int GetTotalFlavorsMade()
      
    {
        
    return flavors.Count;
      }

    }


    public class Client
    {
      
    private static FlavorFactory flavorFactory;
      
    private static int ordersMade = 0;

      
    public static void Main( string[] args )
      
    {
        flavorFactory 
    = new FlavorFactory();

        TakeOrder(
    "Black Coffee");


    凡是有該標(biāo)志的文章,都是該blog博主Caoer(草兒)原創(chuàng),凡是索引、收藏
    、轉(zhuǎn)載請注明來處和原文作者。非常感謝。

    posted on 2006-02-16 09:04 草兒 閱讀(1270) 評論(1)  編輯  收藏 所屬分類: 設(shè)計模式

    Feedback

    # re: 享元(Flyweight)模式 2006-05-25 19:26 pc
    http://www.kpwang.com/pc/view.jsp?board_id=1&article_id=200645223821
    Java常見問題集錦(轉(zhuǎn)載)

    http://www.kpwang.com/pc/view.jsp?board_id=1&article_id=200645223641
    java中的易混問題收集

    http://www.kpwang.com/pc/view.jsp?board_id=1&article_id=20064522334
    Java學(xué)習(xí)過程的一些重點  回復(fù)  更多評論
      

    主站蜘蛛池模板: 日本一区免费电影| 99在线精品视频观看免费| 免费黄网在线观看| 91午夜精品亚洲一区二区三区| 免费精品一区二区三区第35| 亚洲综合国产一区二区三区| 精品久久久久久无码免费| 国产亚洲老熟女视频| a级毛片高清免费视频| 亚洲国产精品SSS在线观看AV| 免费毛片在线看不用播放器 | 在线天堂免费观看.WWW| 亚洲综合久久一本伊伊区| 日韩欧美一区二区三区免费观看| 最新亚洲精品国偷自产在线| 精品免费国产一区二区三区 | 中文字幕亚洲天堂| 免费无码又爽又刺激一高潮| 亚洲无删减国产精品一区| 成人黄色免费网址| 激情小说亚洲色图| 亚洲日韩小电影在线观看| 91香蕉国产线观看免费全集| 亚洲男人天堂2018av| 亚洲国产精品成人久久蜜臀| 国产午夜无码精品免费看| 亚洲18在线天美| 亚洲精品久久久www| 特级无码毛片免费视频尤物 | 特级毛片免费播放| 国产AV无码专区亚洲AV毛网站 | 亚洲av再在线观看| 四虎影视在线影院在线观看免费视频 | 一级全免费视频播放| 亚洲日本在线观看| 波多野结衣久久高清免费 | 亚洲制服丝袜中文字幕| 亚洲欧洲久久久精品| 最好看的中文字幕2019免费| 美女被免费网站在线视频免费 | yy一级毛片免费视频|