設計模式之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;
        }
    }
}

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章