建立型模式之單例模式
阿新 • • 發佈:2020-08-13
定義與特點
單例(Singleton)模式的定義:指一個類只有一個例項,且該類能自行建立這個例項的一種模式。
例如,Windows 中只能開啟一個工作管理員,這樣可以避免因開啟多個工作管理員視窗而造成記憶體資源的浪費,或出現各個視窗顯示內容的不一致等錯誤。
單例模式有 3 個特點:
- 單例類只有一個例項物件;
- 該單例物件必須由單例類自行建立;
- 單例類對外提供一個訪問該單例的全域性訪問點;
結構與實現
單例模式是設計模式中最簡單的模式之一。通常,普通類的建構函式是公有的,外部類可以通過“new 建構函式()”來生成多個例項。但是,如果將類的建構函式設為私有的,外部類就無法呼叫該建構函式,也就無法生成多個例項
單例模式的結構
單例模式的主要角色如下:
- 單例類:包含一個例項且能自行建立這個例項的類。
- 訪問類:使用單例的類。
2. 單例模式的實現
Singleton 模式通常有兩種實現形式:懶漢式單例、餓漢式單例。
第 1 種:懶漢式單例
該模式的特點是類載入時沒有生成單例,只有當第一次呼叫 Getlnstance 方法時才去建立這個單例。程式碼如下:
/// <summary> /// 單例模式的實現-懶漢式單例 /// </summary> public class Singleton { // 定義一個靜態變數來儲存類的例項 private static Singleton instance; // 定義一個標識確保執行緒同步 private static readonly object locker = new object(); // 定義私有建構函式,使外界不能建立該類例項 private Singleton(){ } /// <summary> /// 定義公有方法提供一個全域性訪問點,同時你也可以定義公有屬性來提供全域性訪問點 /// </summary> /// <returns></returns> public static Singleton GetInstance() { // 如果類的例項不存在則鎖定建立過程,否則直接返回 if (instance == null) { lock (locker) { // 如果類的例項不存在則建立,否則直接返回 if (instance == null) { instance = new Singleton(); } } } return instance; } }
第 2 種:餓漢式單例
該模式的特點是類一旦載入就建立一個單例,保證在呼叫 GetInstance 方法之前單例已經存在了。程式碼如下:
/// <summary> /// 單例模式的實現-餓漢式單例 /// </summary> public class Singleton { // 定義一個靜態變數來儲存類的例項 private static Singleton instance=new Singleton(); // 定義私有建構函式,使外界不能建立該類例項 private Singleton() { } /// <summary> /// 定義公有方法提供一個全域性訪問點,同時你也可以定義公有屬性來提供全域性訪問點 /// </summary> /// <returns></returns> public static Singleton GetInstance() { return instance; } }
應用場景
前面分析了單例模式的結構與特點,以下是它通常適用的場景的特點:
- 在應用場景中,某類只要求生成一個物件的時候,如一個班中的班長、每個人的身份證號等。
- 當物件需要被共享的場合。由於單例模式只允許建立一個物件,共享該物件可以節省記憶體,並加快物件訪問速度。如 Web 中的配置物件、資料庫的連線池等。
- 當某類需要頻繁例項化,而建立的物件又頻繁被銷燬的時候,如多執行緒的執行緒池、網路連線池等。
擴充套件:多例模式
單例模式可擴充套件為多例(Multition)模式,這種模式可生成多個例項並儲存在 List 中,客戶需要時可隨機獲取,其結構圖如圖所示:
多例模式可分為以下兩種:
- 有上限多例模式:多例類的例項數目有上限,已經把例項的上限當做邏輯的一部分,並創造到了多例類的內部,這種多例模式叫做有上限多例模式。
- 無上限多例模式:多例類的例項數目並不需要有上限,例項數目並沒有上限的多例模式就叫做無上限多例模式。