分類
建立型模式。
這個模式在解決什麼
單例模式想處理的是:某個類別在系統中只應該有一個實例,而且大家都要透過同一個入口來取得它。
常見原因是這個物件代表某種全域協調者,例如設定管理、流程控制器或共享服務容器。
核心做法
做法通常包含三件事:
- 把建構子設成私有,避免外部直接建立
- 由類別自己保管唯一實例
- 對外提供固定入口讓其他程式取得該實例
什麼時候適合用
如果某個物件在整個系統裡只該存在一份,而且多份實例會造成狀態衝突,就可以考慮單例模式。
但這個模式也很容易被濫用。只要不是明確的全域唯一職責,就不該因為「取用方便」而直接做成單例,否則測試、依賴管理和生命週期控制都會變差。
例子
像遊戲中的總流程管理器、全域設定管理器,或某些確定只該有一份的服務控制器,都可能採用單例模式。前提是你真的接受它是全域共享狀態,而不是把一般物件硬塞成全域入口。
類圖

示例代碼
延遲實例化版本:
public class Singleton
{
private static Singleton instance;
private Singleton() {}
public static Singleton GetInstance()
{
if (instance == null)
{
instance = new Singleton();
}
return instance;
}
}
急切實例化版本:
public class Singleton
{
private static readonly Singleton instance = new Singleton();
private Singleton() {}
public static Singleton GetInstance()
{
return instance;
}
}
使用時要注意
- 延遲實例化比較省資源,但多執行緒情境要特別留意同步問題
- 急切實例化比較單純,但如果實例很重、又不一定會用到,就可能浪費資源
- 單例常常會把依賴藏成全域狀態,長期來看要小心測試成本
這一篇先記住的重點
- 單例模式保證唯一實例,並提供全域存取入口
- 它適合少數真正「只能有一份」的對象
- 方便不代表應該濫用,尤其在大型專案中更要節制
參考書目
《Head First Design Patterns》Eric Freeman, Elisabeth Robson, Kathy Sierra, Bert Bates