不久前剛好被學弟問到關於設計模式的問題,覺得滿有趣的,所以放上來與大家分享一下。
獨體模式其實大家很常使用到,但或許大家不知道他叫獨體模式。
獨體模式又稱為單例模式,目的是為了讓
該物件只能實體化一次,往後每次調用都是相同的物件
而在介紹之前,我們先談談這個獨體模式,他可以使用在哪些情況下。
畢竟我們如果連一開始在何處使用都不知道,那在學習上也只會很空泛,是吧?
獨體模式使用場景
前面剛剛有說過,獨體模式相信有在寫程式的一定都有使用過,只是自己不知道它也是23種設計模式中的其中一種罷了。
他的應用範圍相當廣泛,隨便舉幾個例子:
1.外部資源:
在我們撰寫多執行緒的時候,一定都會遇到當資源有限的情況下,只能有一個Client可以取得該資源時,同一時間我們該如何去判斷只有一位Client可以獲取資源。
這就是獨體模式。
2. Windows的Task Manager(任務管理器)
相信大家都有開啟過Windows的TaskManager吧?其實它就是很典型的獨體模式,我們可以操作看看,你會發現在同一時間內我們無法打開兩個windows task manager
有興趣的可以自己試試看哦~
3.網站的計數器
一般我們在統計該網站的訪問人數時,也是採用獨體模式實現。
假設該站總瀏覽次數為1000次,在同一時間內,有一個以上的Client瀏覽了該網站,如果我們不能及時的將總瀏覽次數進行Lock,那麼同一時間內我們該如何計算瀏覽次數+1呢是吧?
簡單介紹完使用場景後,接下來我們來介紹一下該如何使用獨體模式呢?
在這邊一樣透過幾個程式碼的範例來講解一下獨體模式的使用方式:
1.透過自訂函式來控制該物件的建立
/// <summary>
/// 透過自訂函數來初始化該物件
/// </summary>
class Singleton
{
private static Singleton singleton;
private Singleton()//禁止外部直接實體化該物件
{
}
public static Singleton GetInstance()
{
if (singleton == null)
{
singleton = new Singleton();
}
return singleton;
}
}
我們可以透過自訂函式來將該物件進行實體化,當物件尚未被實體化時,才執行 new
關鍵字
這是第一種最基本的方式,我們禁止外部可以實體化該物件,並由自訂函式來實現,此種方式能確保在程式的生命週期中,只會有一個實體產生。
2.透過自訂函式來控制該物件的建立(使用sealed
與readonly
關鍵字限定物件多次建立)
/// <summary>
/// 利用sealed 限定該類別不能被繼承 透過readonly限定初始化時機
/// </summary>
sealed class SealedSingleton
{
private static readonly SealedSingleton instance = new SealedSingleton();
private SealedSingleton() { }
public static SealedSingleton GetInstance()
{
return instance;
}
}
這個例子與第一種相同,都是透過自訂函式來進行該物件的調用。不過唯一不一樣的是,在這邊我們利用了sealed
與readonly
關鍵字。
我們都知道,類別一但被繼承的時候,會自動初始化父類別的欄位以及建構元的部分,因此我們加上sealed
關鍵字,讓他不允許被繼承
如此一來,我們能確保目前第一步的該物件只會有一個實體存在。
接著在欄位變數的初始化上,我們將在物件前面加上了 readonly
,讓該變數只能在欄位或是建構元當中進行物件的初始化,其餘地方禁止進行初始化。
會做這一步的用途在於,限定我們的物件在這一隻程式底下只會有一個instance產生。
3.在多執行緒上,確保只有一個物件實體存在
/// <summary>
/// 利用lock來確保同一時間只會有一個實體產生
/// </summary>
class SingletonLock
{
private static SingletonLock instance;
private static readonly object syncRoot = new object();
private SingletonLock()
{
}
public static SingletonLock GetInstance()
{
if (instance == null) //確保當前沒有這個物件存在
{
lock (syncRoot)//鎖住當前狀態
{
if (instance == null)//再次確認該物件不存在
{
instance = new SingletonLock();
}
}
}
return instance;
}
最後一種方式則是在當我們使用 Multi-Thread 時,為了確保只會有一個物件實體存在,我們可以透過lock
這個關鍵字
確保同一時間不會有一個以上的物件實體存在。
使用方法與 java的synchronized
相同,在這邊就不多做說明了。
以上就是獨體模式的相關介紹以及各種的使用方式。
以上文章敘述如有錯誤及觀念不正確,請不吝嗇指教:)
有任何家教、案子 或技術相關問題 請都歡迎聯繫我