
想像你在做一個文字編輯器。一篇文章有一萬個字,每個字都有字型、大小、顏色等資訊。如果每個字都獨立儲存這些資訊,記憶體就爆了。
但其實大部分字的字型和大小都一樣,不一樣的只是「內容」和「位置」。把共同的部分抽出來共用——這就是 Flyweight。
先講結論
Flyweight 把物件的狀態分成兩種:
- Intrinsic(可共享):不隨上下文變化的,可以被多個物件共用(例如:交易類型名稱、描述)
- Extrinsic(不可共享):每個物件獨有的(例如:交易金額、備註)
共享的部分用工廠管理,確保同樣的 intrinsic state 只建立一次。
classDiagram class TransactionType { -name : String -description : String +getInfo() String } class TransactionTypeFactory { -types : Map +getTransactionType(name, desc) TransactionType } class Transaction { -transactionType : TransactionType -details : String -amount : Number +getDescription() String } TransactionTypeFactory ..> TransactionType : 快取與回傳 Transaction o-- TransactionType : 共享內部狀態
實戰:交易系統

// Flyweight:可共享的交易類型
class TransactionType {
constructor(name, description) {
this.name = name;
this.description = description;
}
getInfo() { return `${this.name}: ${this.description}`; }
}
// 工廠:確保同一種 type 只建一次
class TransactionTypeFactory {
constructor() { this.types = new Map(); }
getTransactionType(name, description) {
const key = `${name}_${description}`;
if (!this.types.has(key)) {
this.types.set(key, new TransactionType(name, description));
}
return this.types.get(key);
}
}
// 每筆交易共用 TransactionType,但有自己的金額和備註
class Transaction {
constructor(transactionType, details, amount) {
this.transactionType = transactionType; // 共享
this.details = details; // 獨有
this.amount = amount; // 獨有
}
getDescription() {
return `[${this.transactionType.getInfo()}] ${this.details} - $${this.amount}`;
}
}
const factory = new TransactionTypeFactory();
// 一萬筆存款交易,但 TransactionType 只有一個實例
const depositType = factory.getTransactionType('存款', '將資金存入帳戶');
const tx1 = new Transaction(depositType, '薪資入帳', 50000);
const tx2 = new Transaction(depositType, '獎金入帳', 10000);
// 兩筆交易共用同一個 TransactionType
console.log(tx1.transactionType === tx2.transactionType); // true什麼時候值得用 Flyweight?
當你有大量物件且它們之間有大量重複的共享狀態時。如果你只有幾十個物件,共享省下的記憶體根本感覺不到,不值得增加複雜度。
典型場景:文字編輯器的字符、遊戲裡的粒子和樹木、地圖上的圖釘樣式。
要付出什麼代價?
程式碼變複雜了——你需要區分哪些狀態可以共享、哪些不行,還要管理一個工廠。如果分錯了,共享的物件被某一方改掉,其他共用者全部跟著錯。
Flyweight 就像共享單車——車子(intrinsic)是公用的,但你騎去哪裡(extrinsic)是你的事。只是有些人把共享單車騎回家就不還了。