單例模式(Singleton)

定義

單例模式(Singleton Pattern)是一種創建型設計模式,目的是確保某個類別在應用程式中只有一個實例,並提供全域存取點。這個實例會在第一次被請求時建立,並在之後的所有請求中重複使用相同的實例。

特點

  • 保證類別在系統中只有一個實例。
  • 提供統一的全域存取方法(如 getInstance())。
  • 實例通常在內部自行建立並管理,外部無法直接實例化。
  • 一般不允許傳入參數,若有需求建議使用其他設計模式(如工廠模式 + 單例)。

優點

  • 實例控制:防止產生多個實例,確保資源的一致性。
  • 節省資源:只建立一個實例,有效節省記憶體與資源消耗。
  • 全域存取點:任何地方都可透過統一方法取得此實例,尤其適用於共用資源,如設定管理器、資料庫連線等。

缺點

  • 不易遵守開閉原則:單例物件容易在多處被引用,修改時需小心影響整個系統。
  • 不符合單一職責原則:單例經常承載多個邏輯職責,造成類別功能膨脹。
  • 不利於測試:因為無法輕易取代或模擬單例,單元測試與相依注入會變得困難。
  • 潛在的執行緒問題:在多執行緒環境中,若未妥善處理同步,可能導致建立多個實例。

常見實作(以 PHP 為例)

class Singleton
{
    private static ?Singleton $instance = null;

    // 私有建構子,禁止外部實例化
    private function __construct()
    {
        // 初始化程式
    }

    // 禁止複製實例
    private function __clone() {}

    // 禁止反序列化
    private function __wakeup() {}

    // 提供統一的存取方法
    public static function getInstance(): Singleton
    {
        if (self::$instance === null) {
            self::$instance = new self();
        }

        return self::$instance;
    }
}

使用情境

  • 設定管理(Config)
  • 資源共享(如資料庫連線、快取物件)
  • 日誌系統(Logger)
  • 多數情況下須謹慎使用,必要時才導入

注意事項

  • 若需傳參數初始化,建議將單例改為延遲初始化並結合設定注入。
  • Laravel 等框架中可使用 Service Container 管理單例(透過 singleton() 方法)。