後端開發 設計模式 · 第 2 / 24 篇

單例模式:只要一個就夠!

單例模式 (Singleton Pattern) 確保一個類別只有一個實例。本文透過 C# 範例,示範如何實作並應用於系統設定管理等場景。

在上一篇文章中,我們簡單認識了什麼是「設計模式」。這次,就讓我們從最經典的「單例模式(Singleton)」開始,看看它究竟能為開發帶來什麼幫助吧!


☕ 小故事:世界上只此一家

想像你開了一間只允許存在一個分店的咖啡廳,無論客人怎麼找,都只能到這家。單例模式的精神也差不多:確保整個應用程式裡只有同一個實例存在。

🤔 什麼情境適合用 Singleton?

  • 系統設定:確保設定檔只有一份,避免各模組各自讀取產生混亂。
  • 日誌記錄:統一紀錄進入點,不會讓檔案四散。
  • 資料庫連線:集中管理連線、節省資源。

接下來的範例將以「系統設定」為主角,用 C# 程式碼示範 Singleton 的實作。

💻 Singleton 類別

using System;

/// <summary>
/// 系統設定管理器,只允許產生一個實例
/// </summary>
public sealed class ConfigurationManager
{
    // 保留唯一實例
    private static ConfigurationManager _instance;
    // 執行緒鎖定物件,確保多執行緒環境下仍只會建立一次
    private static readonly object _lock = new object();

    /// <summary>
    /// 連線字串設定
    /// </summary>
    public string ConnectionString { get; private set; }

    // 建構子設為私有,阻止外部直接建立
    private ConfigurationManager()
    {
        Console.WriteLine("建立 ConfigurationManager 唯一實例");
        // 模擬載入設定值
        ConnectionString = "Server=myServer;Database=myDB;User Id=myUser;";
    }

    /// <summary>
    /// 取得唯一實例的存取點
    /// </summary>
    public static ConfigurationManager Instance
    {
        get
        {
            if (_instance == null)
            {
                lock (_lock)
                {
                    if (_instance == null)
                    {
                        _instance = new ConfigurationManager();
                    }
                }
            }
            return _instance;
        }
    }
}

🚀 實際使用範例

using System;

class Program
{
    static void Main(string[] args)
    {
        // 第一次取得實例
        ConfigurationManager config1 = ConfigurationManager.Instance;

        // 再次取得同一個實例
        ConfigurationManager config2 = ConfigurationManager.Instance;

        if (config1 == config2)
        {
            Console.WriteLine("確認過眼神,是同一個 Singleton 實例!");
            Console.WriteLine("設定資料庫連線字串為:" + config1.ConnectionString);
        }
    }
}

🎯 執行結果

建立 ConfigurationManager 唯一實例
確認過眼神,是同一個 Singleton 實例!
設定資料庫連線字串為:Server=myServer;Database=myDB;User Id=myUser;

Singleton 使用上的小提醒

  • 過度依賴單例物件,可能讓程式難以測試。
  • 單例本質上是一種全域狀態,過多使用容易增加耦合度。

結語

第一個模式就先分享到這裡,希望你對 Singleton 已經有更清楚的認識。下篇文章,我們會再往下一個設計模式邁進,敬請期待!

系列:

讀完了!你覺得這篇如何?

你的回饋會決定下一篇要寫什麼。

還有疑問

Learning path

設計模式

這篇是系列中的第 2 / 24 篇。可以順著列表補完整脈絡,也可以直接跳到需要的段落。

  1. 01 搞懂設計模式到底是什麼?
  2. 02 單例模式:只要一個就夠! 目前閱讀
  3. 03 工廠方法模式:點披薩不用親自下廚
  4. 04 抽象工廠模式:系列產品輕鬆生產
  5. 05 原型模式:複製的藝術
  6. 06 建造者模式:一步步完成複雜任務
  7. 07 介面卡模式:讓不相容也能合作
  8. 08 橋接模式:抽象與實作分離
  9. 09 組合模式:樹狀結構的好幫手
  10. 10 裝飾者模式:讓功能自由加點
  11. 11 外觀模式:化繁為簡
  12. 12 享元模式:節省記憶體的利器
  13. 13 代理模式:控制存取的守門員
  14. 14 責任鏈模式:層層把關的處理機制
  15. 15 命令模式:靈活封裝的請求指令
  16. 16 解譯器模式:讓程式聽懂你的指令
  17. 17 迭代器模式:輕鬆遍歷集合元素
  18. 18 中介者模式:管理複雜溝通的好幫手
  19. 19 備忘錄模式:保存與恢復物件狀態
  20. 20 觀察者模式:即時通知的好幫手
  21. 21 狀態模式:依狀態改變行為的祕訣
  22. 22 策略模式:靈活切換行為的好幫手
  23. 23 模板方法模式:固定流程靈活實作
  24. 24 訪問者模式:新增功能不動既有架構

Further reading

中介者模式:管理複雜溝通的好幫手 封面圖 2025-06-13 中介者模式:管理複雜溝通的好幫手 備忘錄模式:保存與恢復物件狀態 封面圖 2025-06-13 備忘錄模式:保存與恢復物件狀態 模板方法模式:固定流程靈活實作 封面圖 2025-06-13 模板方法模式:固定流程靈活實作

留言討論

用 GitHub 帳號留言,留言會同步到這個 Blog 的 GitHub Discussions。

閱讀導覽

約 2 分鐘

本篇所在系列 · 第 2 / 24 篇

設計模式

  1. 搞懂設計模式到底是什麼?
  2. 單例模式:只要一個就夠!
  3. 工廠方法模式:點披薩不用親自下廚
  4. 抽象工廠模式:系列產品輕鬆生產
  5. 原型模式:複製的藝術
  6. 建造者模式:一步步完成複雜任務
  7. 介面卡模式:讓不相容也能合作
  8. 橋接模式:抽象與實作分離
  9. 組合模式:樹狀結構的好幫手
  10. 裝飾者模式:讓功能自由加點
  11. 外觀模式:化繁為簡
  12. 享元模式:節省記憶體的利器
  13. 代理模式:控制存取的守門員
  14. 責任鏈模式:層層把關的處理機制
  15. 命令模式:靈活封裝的請求指令
  16. 解譯器模式:讓程式聽懂你的指令
  17. 迭代器模式:輕鬆遍歷集合元素
  18. 中介者模式:管理複雜溝通的好幫手
  19. 備忘錄模式:保存與恢復物件狀態
  20. 觀察者模式:即時通知的好幫手
  21. 狀態模式:依狀態改變行為的祕訣
  22. 策略模式:靈活切換行為的好幫手
  23. 模板方法模式:固定流程靈活實作
  24. 訪問者模式:新增功能不動既有架構
看完整系列 24 篇