cover

Flyweight 模式:共享共用狀態

Flyweight 模式把可共享的內部狀態抽出來共用,避免大量重複物件耗費記憶體。

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 : 共享內部狀態
    note for TransactionType "intrinsic state\n可被多個 Transaction 共用"

使用情境

  1. 文字編輯器:字型與格式共享。
  2. 遊戲場景:粒子、樹木共用材質。
  3. 交易系統:交易類型共用。

實作範例

Flyweight 模式:共享池提供重複使用的物件

class TransactionType {
  constructor(name, description) {
    this.name = name;
    this.description = description;
  }
 
  getInfo() {
    return `${this.name}: ${this.description}`;
  }
}
 
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);
  }
}
 
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();
const depositType = factory.getTransactionType('存款', '將資金存入帳戶');
const tx = new Transaction(depositType, '薪資入帳', 50000);
console.log(tx.getDescription());

優點

  • 大量物件時省記憶體
  • 提升效能

缺點

  • 需要區分可共享與不可共享狀態

延伸閱讀