cover

Object Pool 模式:重複使用昂貴資源

Object Pool 模式維護一個可重複使用的物件池,讓物件可借用與歸還。

classDiagram
    class ConnectionPool {
        -size : Number
        -available : Connection[]
        -inUse : Connection[]
        +initialize() void
        +acquireConnection() Connection
        +releaseConnection(conn) void
    }
    class Connection {
        -id : Number
        -inUse : boolean
        +connect() void
        +execute(query) Result
        +reset() void
    }
    ConnectionPool o-- Connection : 管理
    note for ConnectionPool "借出 → 使用 → 歸還\n避免重複建立"

使用情境

  1. 資料庫連線池:重複使用連線。
  2. 執行緒池:避免頻繁建立執行緒。
  3. 網路連線池:Socket 連線重用。

實作範例

Object Pool 模式:物件借用與歸還的共享池

class Connection {
  constructor(id) {
    this.id = id;
    this.inUse = false;
  }
 
  async connect() {
    await new Promise(resolve => setTimeout(resolve, 50));
    console.log(`連線 ${this.id} 已建立`);
  }
 
  async execute(query) {
    console.log(`連線 ${this.id} 執行: ${query}`);
    return { success: true, connectionId: this.id };
  }
 
  reset() {
    this.inUse = false;
  }
}
 
class ConnectionPool {
  constructor(size) {
    this.size = size;
    this.available = [];
    this.inUse = [];
    this.initialized = false;
  }
 
  async initialize() {
    for (let i = 0; i < this.size; i++) {
      const conn = new Connection(i + 1);
      await conn.connect();
      this.available.push(conn);
    }
    this.initialized = true;
  }
 
  async acquireConnection() {
    if (!this.initialized) {
      await this.initialize();
    }
 
    if (this.available.length === 0) {
      throw new Error('連線池已滿,無法取得連線');
    }
 
    const connection = this.available.pop();
    connection.inUse = true;
    this.inUse.push(connection);
    return connection;
  }
 
  async releaseConnection(connection) {
    const index = this.inUse.indexOf(connection);
    if (index === -1) {
      throw new Error('該連線不屬於此連線池');
    }
 
    this.inUse.splice(index, 1);
    connection.reset();
    this.available.push(connection);
  }
}
 
async function main() {
  const pool = new ConnectionPool(2);
  const conn1 = await pool.acquireConnection();
  await conn1.execute('SELECT * FROM users');
  await pool.releaseConnection(conn1);
}
 
main();

優點

  • 節省建立與銷毀成本
  • 資源使用可控

缺點

  • 需要額外管理邏輯

延伸閱讀