關於 Singleton 本篇將討論以下幾個問題
1. 關於 Singleton
2. UML
3. 將 UML 轉為程式碼
4. 情境
測試環境:
OS:Windows 10
IDE:Visual Studio 2019
1. 關於 Singleton
Ensure a class only has one instance, and provide a global point of access to it.
by Gang of Four
- 確保 Singleton class 只有一個實體,並提供全局對這個實體的訪問點
Singleton(單例)屬於創建型(Creational Patterns),當遇到不同呼叫端需要取得相同實體時可以使用 singleton,不過 singleton 由於許多缺點,所以並不建議用於解決複雜情形的簡化,而是在取得相同實體時才採用。
優點:
- 確保每次取得都是同一個實體,只有實體不存在時才需要初始化
缺點:
- 需考慮到 thread safe 問題
- 對於抽象、繼承、多型支援度較差
- 單元測試較麻煩
2. UML
Class:
- Singleton:作為單例的實體
3. 將 UML 轉為程式碼
此範例的寫法不是 thread safe,關於 Singleton 的 thread safe 寫法可參考 C# in Depth
建立Singleton
實體,_instance
不存在才會 new 出新的實體
/// <summary>
/// Singleton 實體
/// </summary>
public class Singleton
{
private static Singleton _instance;
// 建構子通常為 protected or private,避免由外部建立實體
protected Singleton()
{
}
public static Singleton Instance()
{
// 使用延遲載入,此方式並非 thread safe
return _instance ??= new Singleton();
}
}
- 分別呼叫
Singleton.Instance()
取得實體 - 比較兩次取得的實體是否相同
static void Main(string[] args)
{
Default.Singleton singletonA = Default.Singleton.Instance();
Default.Singleton singletonB = Default.Singleton.Instance();
if (singletonA == singletonB)
{
Console.WriteLine("\nSame instance");
}
Console.ReadLine();
}
執行結果
Same instance
4. 情境
我們接到了一個線上商城取得倉庫庫存量資訊的需求
- 倉庫庫存資訊不提供外部修改
- 倉庫庫存資訊資料量很大,很佔記憶體空間
建立InStockModel
實體,_instance
不存在才會 new 出新的實體
/// <summary>
/// Singleton 實體
/// </summary>
public class InStockModel
{
private static InStockModel _instance;
protected InStockModel()
{
Console.WriteLine($"Get in stock data by API.");
}
public static InStockModel Instance()
{
// 使用延遲載入,此方式並非 thread safe
return _instance ??= new InStockModel();
}
}
- 分別呼叫
InStockModel.Instance()
取得實體 - 確認是否只有在第一次呼叫時進入建構子
- 比較兩次取得的實體是否相同
static void Main(string[] args)
{
Situation.InStockModel inStockModelA = Situation.InStockModel.Instance();
Situation.InStockModel inStockModelB = Situation.InStockModel.Instance();
if (inStockModelA == inStockModelB)
{
Console.WriteLine("\nSame instance");
}
Console.ReadLine();
}
執行結果
Get in stock data by API.
Same instance
完整程式碼
GitHub:Creational_05_Singleton