C#設計中單例模式例項講解
前言
最近開始花點心思研究下設計模式,主要還是讓自己寫的程式碼可重用性高、保證程式碼可靠性。所謂設計模式,我找了下定義:是一套被反覆使用、多數人知曉的、經過分類編目的、程式碼設計經驗的總結。毫無疑問,設計模式於己於他人於系統都是多贏的;設計模式使程式碼編制真正工程化;設計模式是軟體工程的基石脈絡,如同大廈的結構一樣。
為什麼要提倡“Design Pattern(設計模式)”?
根本原因是為了程式碼複用,增加可維護性。因此這次我們來學習下設計模式,最後會透過C#語言來實現這些設計模式作為例子,深刻理解其中的精髓。
定義
單例模式是一種常用的軟體設計模式。在它的核心結構中只包含一個被稱為單例類的特殊類。透過單例模式可以保證系統中一個類只有一個例項而且該例項易於外界訪問,從而方便對例項個數的控制並節約系統資源。如果希望在系統中某個類的物件只能存在一個,單例模式是最好的.解決方案。
特點
1、 某個類只能有一個例項
2、它必須自行建立這個例項
3、它必須自行向整個系統提供這個例項。
優缺點
優點:
一、例項控制
單例模式會阻止其他物件例項化其自己的單例物件的副本,從而確保所有物件都訪問唯一例項。
二、靈活性
因為類控制了例項化過程,所以類可以靈活更改例項化過程。
缺點:
一、開銷
雖然數量很少,但如果每次物件請求引用時都要檢查是否存在類的例項,將仍然需要一些開銷。可以透過使用靜態初始化解決此問題。
二、可能的開發混淆
使用單例物件(尤其在類庫中定義的物件)時,開發人員必須記住自己不能使用new關鍵字例項化物件。因為可能無法訪問庫原始碼,因此應用程式開發人員可能會意外發現自己無法直接例項化此類。
三、物件生存期
不能解決刪除單個物件的問題。在提供記憶體管理的語言中(例如基於.NET Framework的語言),只有單例類能夠導致例項被取消分配,因為它包含對該例項的私有引用。在某些語言中(如 C++),其他類可以刪除物件例項,但這樣會導致單例類中出現懸浮引用。
複製程式碼 程式碼如下:
///
/// 單例模式
///
public class Singleton
{
// 定義一個靜態變數來儲存類的例項
private static Singleton mySingleton;
// 定義私有建構函式,使外界不能建立該類例項
private Singleton()
{
}
//定義公有方法提供一個全域性訪問點。
public static Singleton GetInstance()
{
//這裡的lock其實使用的原理可以用一個詞語來概括“互斥”這個概念也是作業系統的精髓
//其實就是當一個程序進來訪問的時候,其他程序便先掛起狀態
if (mySingleton == null)
{
mySingleton = new Singleton();
}
return mySingleton;
}
}
上面的單例模式的實現是有問題的,當多個使用者或者方法同時訪問的時候,便會出現多個使用者同時拿到了mySingleton==null的結果,這個明顯不是我們想要的,因此,我們應該透過一個鎖來互斥這個方法,當很多執行緒同時訪問的時候,只允許一個執行緒進入到程式碼中執行,而其他的便只能處於掛起的狀態。
複製程式碼 程式碼如下:
///
/// 單例模式
///
public class Singleton
{
// 定義一個靜態變數來儲存類的例項
private static Singleton mySingleton;
// 定義一個標識確保執行緒同步
private static readonly object locker = new object();
// 定義私有建構函式,使外界不能建立該類例項
private Singleton()
{
}
//定義公有方法提供一個全域性訪問點。
public static Singleton GetInstance()
{
//這裡的lock其實使用的原理可以用一個詞語來概括“互斥”這個概念也是作業系統的精髓
//其實就是當一個程序進來訪問的時候,其他程序便先掛起狀態
if (mySingleton == null)//區別就在這裡
{
lock (locker)
{
// 如果類的例項不存在則建立,否則直接返回
if (mySingleton == null)
{
mySingleton = new Singleton();
}
}
}
return mySingleton;
}
}
其實在一些專案中,單例模式早就有了體現。在開發asp.net的專案中,就已經用這種方法來包裝http上下文來實現計算機資源的節省。
複製程式碼 程式碼如下:
///
/// 業務倉儲
///
public IBLL.IBLLSession BLLSession;
//---------------------定義上下文屬性
#region 例項建構函式 初始化業務倉儲 + OperateContext()
public OperateContext()
{
BLLSession = DI.SpringHelper.GetObject
}
#endregion
#region Http上下文 以及相關屬性
///
/// Http上下文
///
HttpContext ContextHttp
{
get
{
return HttpContext.Current;
}
}
HttpResponse Response
{
get
{
return ContextHttp.Response;
}
}
HttpRequest Request
{
get
{
return ContextHttp.Request;
}
}
HttpSessionState Session
{
get
{
return ContextHttp.Session;
}
}
#endregion
#region 獲取當前操作上下文(存線上程中,提高效率) + OperateContext Current
//
/// 獲取當前操作上下文(存線上程中,提高效率)
///
public static OperateContext Current
{
get
{
OperateContext o = CallContext.GetData(typeof(OperateContext).Name) as OperateContext;
if (o == null)
{
o = new OperateContext();
CallContext.SetData(typeof(OperateContext).Name, o);
}
return o;
}
}
#endregion
總結
到這裡,就和大家一起先了解了單例模式到底是個什麼東西,其實在一些專案中,這種模式就已經應用了,只是我們沒有去發現和總結,不過本來設計模式就是一套被反覆使用、多數人知曉的、經過分類編目的、程式碼設計經驗的總結。哎。。。。這次是第二次編輯了,本來這個單例模式已經發布了好多天,竟然被我新的一篇觀察者模式給覆蓋了,資料取不回來,只能匆匆完稿,大家見諒啊,有問題我們一起來討論,畢竟我也是初學者。