首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

設計模式探討:Flyweight 模式

     編輯:Java 相關知識

Flyweight 定義:避免大量擁有相同內容的小型物件開銷(如記憶體耗盡),透過共享單一元類別(Meta-class)實現。

動機

物件導向原則雖主張「萬物皆物件」,但若每個字元皆建立物件(如文字處理軟體),數千字即產生數千物件,嚴重消耗記憶體。須「求同存異」,萃取物件群共同點設計元類別封裝可共享部分(內部狀態,intrinsic state),而依賴應用情境(Context)且不可共享的部分為外部狀態(extrinsic state)。

簡言之:先建立原始模型,再依不同場合產生具特徵的具體模型。Flyweight 模式常搭配 Factory 模式:Flyweight Factory 維護 Flyweight Pool 存放內部狀態物件。此模式能顯著提升程式效能與執行速度,適用場合廣泛(如資料庫讀取大量重複字串,可存入 Flyweight Pool)。

實作架構

1. Flyweight 介面

public interface Flyweight {
    public void operation(ExtrinsicState state);
}
public interface ExtrinsicState { }

2. 可共享具體實作

ConcreteFlyweight 必須可共享,儲存的狀態皆為內部狀態,與應用環境無關。

public class ConcreteFlyweight implements Flyweight {
    private IntrinsicState state;
    public void operation(ExtrinsicState state) {
        // 具體操作邏輯
    }
}

3. 不共享具體實作

並非所有子類別都需共享。

public class UnsharedConcreteFlyweight implements Flyweight {
    public void operation(ExtrinsicState state) { }
}

4. Flyweight Factory

管理 Flyweight Pool,請求時優先查找池中現有物件,否則建立新物件加入池中並回傳。

public class FlyweightFactory {
    private Hashtable flyweights = new Hashtable();
    public Flyweight getFlyweight(Object key) {
        Flyweight flyweight = (Flyweight) flyweights.get(key);
        if (flyweight == null) {
            flyweight = new ConcreteFlyweight();
            flyweights.put(key, flyweight);
        }
        return flyweight;
    }
}

5. 用戶端呼叫

FlyweightFactory factory = new FlyweightFactory();
Flyweight fly1 = factory.getFlyweight("Fred");
Flyweight fly2 = factory.getFlyweight("Wilma");

表面看似單純 Factory 用法,奧妙在 Factory 內部共享機制。

XML 資料源應用範例

以唱片 CD 為例,XML 儲存多張 CD 資料:發行年份、歌手、曲目。歌手姓名常重複(同一歌手多張專輯),適合作為可共享的 ConcreteFlyweight;年份與曲目為不可共享部分。

資料模型

public class CD {
    private String title;
    private int year;
    private Artist artist;  // 共享物件
    // getter/setter...
}

public class Artist {  // ConcreteFlyweight
    private String name;  // 內部狀態
    String getName() { return name; }
    Artist(String n) { name = n; }  // immutable
}

Artist Factory

public class ArtistFactory {
    Hashtable pool = new Hashtable();
    Artist getArtist(String key) {
        Artist result = (Artist) pool.get(key);
        if (result == null) {
            result = new Artist(key);
            pool.put(key, result);
        }
        return result;
    }
}

當 CD 數量達數千甚至更多,Flyweight 模式節省記憶體效果顯著,共享物件越多節省越大。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved