實現物件的複用——享元模式(二)

Liuwei-Sunny發表於2012-06-15
      享元模式結構較為複雜,一般結合工廠模式一起使用,在它的結構圖中包含了一個享元工廠類,其結構圖如圖14-3所示:

 

14-3 享元模式結構圖

      在享元模式結構圖中包含如下幾個角色:

      ● Flyweight(抽象享元類):通常是一個介面或抽象類,在抽象享元類中宣告瞭具體享元類公共的方法,這些方法可以向外界提供享元物件的內部資料(內部狀態),同時也可以通過這些方法來設定外部資料(外部狀態)。

      ● ConcreteFlyweight(具體享元類):它實現了抽象享元類,其例項稱為享元物件;在具體享元類中為內部狀態提供了儲存空間。通常我們可以結合單例模式來設計具體享元類,為每一個具體享元類提供唯一的享元物件。

      ● UnsharedConcreteFlyweight(非共享具體享元類):並不是所有的抽象享元類的子類都需要被共享,不能被共享的子類可設計為非共享具體享元類;當需要一個非共享具體享元類的物件時可以直接通過例項化建立。

      ● FlyweightFactory(享元工廠類):享元工廠類用於建立並管理享元物件,它針對抽象享元類程式設計,將各種型別的具體享元物件儲存在一個享元池中,享元池一般設計為一個儲存“鍵值對”的集合(也可以是其他型別的集合),可以結合工廠模式進行設計;當使用者請求一個具體享元物件時,享元工廠提供一個儲存在享元池中已建立的例項或者建立一個新的例項(如果不存在的話),返回新建立的例項並將其儲存在享元池中。

      在享元模式中引入了享元工廠類,享元工廠類的作用在於提供一個用於儲存享元物件的享元池,當使用者需要物件時,首先從享元池中獲取,如果享元池中不存在,則建立一個新的享元物件返回給使用者,並在享元池中儲存該新增物件。典型的享元工廠類的程式碼如下:

class FlyweightFactory {

    //定義一個HashMap用於儲存享元物件,實現享元池

       private HashMap flyweights = newHashMap();

      

       public Flyweight getFlyweight(String key){

              //如果物件存在,則直接從享元池獲取

              if(flyweights.containsKey(key)){

                     return(Flyweight)flyweights.get(key);

              }

              //如果物件不存在,先建立一個新的物件新增到享元池中,然後返回

              else {

                     Flyweight fw = newConcreteFlyweight();

                     flyweights.put(key,fw);

                     return fw;

              }

       }

}

      享元類的設計是享元模式的要點之一,在享元類中要將內部狀態和外部狀態分開處理,通常將內部狀態作為享元類的成員變數,而外部狀態通過注入的方式新增到享元類中。典型的享元類程式碼如下所示:

class Flyweight {

     //內部狀態intrinsicState作為成員變數,同一個享元物件其內部狀態是一致的

       private String intrinsicState;

      

       public  Flyweight(String intrinsicState) {

              this.intrinsicState=intrinsicState;

       }

      

        //外部狀態extrinsicState在使用時由外部設定,不儲存在享元物件中,即使是同一個物件,在每一次呼叫時也可以傳入不同的外部狀態

       public void operation(String  extrinsicState) {

              ......

       }     

}

【作者:劉偉  http://blog.csdn.net/lovelion

相關文章