享元模式結構較為複雜,一般結合原廠模式一起使用,在它的結構圖中包含了一個享元工廠類,其結構圖14-3所示:
圖14-3 享元模式結構圖
在享元模式結構圖中包含如下幾個角色:
● Flyweight(抽象享元類):通常是一個介面或抽象類別,在抽象享元類中聲明了具體享元類公用的方法,這些方法可以向外界提供享元對象的內部資料(內部狀態),同時也可以通過這些方法來設定外部資料(外部狀態)。
● ConcreteFlyweight(具體享元類):它實現了抽象享元類,其執行個體稱為享元對象;在具體享元類中為內部狀態提供了儲存空間。通常我們可以結合單例模式來設計具體享元類,為每一個具體享元類提供唯一的享元對象。
● UnsharedConcreteFlyweight(非共用具體享元類):並不是所有的抽象享元類的子類都需要被共用,不能被共用的子類可設計為非共用具體享元類;當需要一個非共用具體享元類的對象時可以直接通過執行個體化建立。
● FlyweightFactory(享元工廠類):享元工廠類用於建立並管理享元對象,它針對抽象享元類編程,將各種類型的具體享元Object Storage Service在一個享元池中,享元池一般設計為一個儲存“索引值對”的集合(也可以是其他類型的集合),可以結合原廠模式進行設計;當使用者請求一個具體享元對象時,享元工廠提供一個儲存在享元池中已建立的執行個體或者建立一個新的執行個體(如果不存在的話),返回新建立的執行個體並將其儲存在享元池中。
在享元模式中引入了享元工廠類,享元工廠類的作用在於提供一個用於儲存享元對象的享元池,當使用者需要對象時,首先從享元池中擷取,如果享元池中不存在,則建立一個新的享元對象返回給使用者,並在享元池中儲存該新增對象。典型的享元工廠類的代碼如下:
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】