1. 程式人生 > >設計模式之13--享元模式

設計模式之13--享元模式

享元模式學習筆記

對於有時候系統中需要產生大量物件的情況,會造成系統性能下降,而這些物件之間的差別可能很小。比如圍棋中的棋子(之間唯一不同的也就是座標),又或者是火車票(相同的都是始發站和目的站,不同的是票的座位)。那麼如果可以做到只儲存一份物件在系統中,又不影響客戶類操作這一系列的物件呢,這邊就需要使用到享元模式。

享元模式能夠以共享的方式做到支援大量細粒度物件的重用,關鍵是享元模式區分內部和外部狀態,內部狀態儲存在享元物件內部並且不會隨著環境的變化而變化,在享元池中正是通過內部狀態來獲得相應的享元物件。而外部狀態正好相反,它是不可以共享的、隨環境改變而改變的,只有在享元物件被建立之後,然後將外部物件傳入那麼就可以得到實際的物件了。(理解的是考慮火車票,比如從上海->北京,1000張票不可能產生1000個物件的,那麼系統只需要在享元池中儲存一個上海->北京的火車票,而表示一個具體的火車票的時候從享元池中取出享元物件然後傳入座位和車廂就可以表示一個具體的車票。那麼上海、北京這就是內部物件,而座位和車廂就是會變的,屬於外部狀態)。

定義:享元模式運用共享技術有效的支援大量細粒度物件的複用。系統只使用少量的物件,而這些物件都很相似,狀態變化很小,可以實現物件的多次複用。由於享元模式要求能夠共享的物件必須是細粒度物件,因此它又稱為輕量級模式,是一種結構型模式。

如下圖就是享元模式的結構圖:

從上圖中可以發現包含如下幾個角色:

  1. FlyWeight抽象享元類:聲明瞭具體享元類的公共的方法,這些方法可以向外部提供享元物件的內部狀態,也可以通過這些方法設定外部狀態。
  2. ConcreteFlyWeight具體享元類:為享元物件的內部狀態提供儲存空間。實現抽象享元類中宣告的方法
  3. UnSharedConcreteFlyWeight非共享具體享元類:需要該類物件的時候直接例項化建立
  4. FlyWeightFactory享元工廠類:建立並管理享元類,我可以通過工廠模式來設計一個享元池,Map
class FlyWeight {
    private String intrinsicState;

    public FlyWeight(String intrinsicState) {
        this.intrinsicState = intrinsicState;
    }

    public void operation(String extrinsicState) {
        /*TODO*/
    }
}

class FlyWeightFactory {
    private
HashMap flyweights = new HashMap(); public FlyWeight getFlyWeight(String key) { if(flyweights.containsKey(key) return (FlyWeight)flyweights.get(key); else { FlyWeight fw = new ConcreteFlyWeight(); flyweights.put(key, fw); return fw; } } }

總結:
如果系統中存在大量相似的細粒度物件,那麼就可以使用享元模式來極大的減少記憶體中物件的數量,不過得需要區分出享元物件的內部狀態和外部狀態。另外可以通過一個享元池來管理系統中的享元物件。