單例模式(Singleton Pattern)是一種創建型設計模式,它確保一個類只有一個實例(instance),並提供一個全局訪問點(Global Access Point)來訪問這個instance。
單例模式通常用於需要共享一個資源或服務的情況,確保該資源或服務只有一個instance存在。
說到這個單例模式,
不得不談談以前在課堂上學過的非同步、多執行緒。
如果筆者沒記錯這段式在作業系統內教導的,
也就是
競爭條件(Race Conditions)、死鎖(Deadlock)、資源競爭(Resource Contention)、線程不安全(Thread-Unsafe)等等。
而其中線程不安全(Thread-Unsafe),
的解決方法是透過同步機制,
而同步機制的具體作法就是:
確保在同一時間只有一個執行緒能夠訪問關鍵資源或區域。
而要達成這個,
通常會要使用靜態,
筆者在第五日簡單介紹過static,
而筆者當時是用非常簡單的概括。
這邊筆者再次舉出static的特性,
如果有實際運用過static,
就會知道static不屬於實例(instance),
而是屬於Class,
因此可以在整個應用程序中通過class本身訪問這些成員,
而這就是提供全局訪問點(Global Access Point)。
而具體的做法就是透過static做出一個Global Access Point,
透過此來製作出lock,
這就是單例模式最常使用的一種例子。
public class Singleton
{
private static Singleton instance;
private Singleton()
{
}
// 靜態方法,返回唯一實例
public static Singleton getInstance() {
if (instance == null) {
// 使用雙重檢查鎖定確保多線程安全性
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
那麼可以明確地觀察出,
單利模式具有全局訪問點,
而這帶來了避免不必要的初始化,
已達成節省內存資源,
通常適用於共享資源。
那麼很明顯這也是非常適合許多創建後銷毀又再次創建一樣的東西,
而這如果各位有用過連線字串,
都會感覺到這很常發生在連線字串中,
而根據剛剛的範例,
稍微改幾個參數,
就會是很常在連線中使用的
public sealed class Connect
{
private static IDBConnect DBConnect;
private static object syncLock = new Object();
public static IDBConnect GetInstance()
{
if (DBConnect == null)
{
lock (syncLock)
{
if (DBConnect == null)
{
DBConnect = //連線;
}
}
}
return DBConnect;
}
}
那麼說了那麼多優點,
單利模式也有許多缺點,
很明顯的從目的就能帶來缺點,
Singleton Pattern需要共享一個資源或服務的情況,確保該資源或服務只有一個instance存在。
那麼如果是變化的對象,就會引起數據錯誤,
也就是競爭條件(Race Condition)。
那麼也可以看出沒有依賴抽象層,
這就是會造成如果要擴張是很難的。
當然還有可能會因為需求太高,
造成職責過重。
可以看出這個模式就是缺乏彈性,
而且容易過度的權責,
導致難以切割。
當然除此之外還有許多是歸於單利模式的方式與,
筆者在此主要著重介紹了雙重檢查鎖定(Double-Check Locking),靜態(Static Inner Class)。
其他筆者知道的還有
Eager Initialization
Lazy Initialization
Enum
那麼關於設計模式這一塊,
筆者就用Singleton Pattern來暫時告一段落,
接下來筆者打算說說開發模式與一些常見的軟體,
如果實在是有一些想不到要怎麼說的話,
還請容許筆者再來介紹很多筆者沒介紹的設計模式。