在某些情況下
,特定型別的資料需要提供給應用程式中的其他所有物件使用。在大多數情況下,這種型別的資料在系統中還是唯一的。
如何使物件例項全域性可用,並保證僅建立乙個此類的例項?
singleton
通過下列方法提供唯一的全域性例項:
? 1.讓類建立自己的唯一例項。
? 2.允許其他物件通過可返回例項引用的類方法來訪問此例項。類方法是全域性可訪問的。
?? 3.將類建構函式宣告為私有,從而任何其他物件都不能建立新例項。
下而是c#實現singleton模式的**:
public class singleton
?? public static singleton instance
?? }
?? private static singleton instance;
} // class singleton
該實現主要有兩個優點:
1.由於例項是在
instance
屬性方法內部建立的,因此類可以使用附加功能(例如,對子類進行例項化),即使它可能引入不想要的依賴性。
2.直到物件要求產生乙個例項才執行例項化;這種方法稱為
"懶例項化
"。懶例項化避免了在應用程式啟動時例項化不必要的singleton。
但是,這種實現的主要缺點是在多執行緒環境下它是不安全的。如果執行過程的不同執行緒同時進入
instance
屬性方法,那麼可能會建立多個
singleton
物件例項。
解決此問題的方法有很多。一種方法是使用被稱為
double-check locking
[lea99]的技術。而c#與公共語言執行庫也提供了一種
"靜態初始化
"方法,這種方法不需要開發人員顯式地編寫執行緒安全**,即可解決這些問題。
靜態初始化
public sealed class singleton
?? private static singleton instance
???}
?? private static readonly singleton instance = new singleton();
} //class singleton
在此策略中,將在第一次引用類的任何成員時建立例項。公共語言執行庫負責處理變數初始化。該類標記為
sealed
以阻止發生派生,而派生可能會增加例項。
此外,變數標記為readonly,這意味著只能在靜態初始化期間(此處顯示的示例)或在類建構函式中分配變數。
該實現與前面的示例類似,不同之處在於它依賴公共語言執行庫來初始化變數。它仍然可以用來解決
singleton
模式試**決的兩個基本問題:全域性訪問和例項化控制。公共靜態屬性為訪問例項提供了乙個全域性訪問點。此外,由於建構函式是私有的,因此不能在類本身以外例項化
singleton
類;因此,變數引用的是可以在系統中存在的唯一的例項。
由於singleton例項被私有靜態成員變數引用,因此在類首次被對
instance
屬性的呼叫所引用之前,不會發生例項化。
這種方法唯一的潛在缺點是,您對例項化機制的控制權較少。在
design patterns
形式中,您能夠在例項化之前使用非預設的建構函式或執行其他任務。由於在此解決方案中由
.net framework
負責執行初始化,因此您沒有這些選項。在大多數情況下,靜態初始化是在.net中實現
singleton
的首選方法。
多執行緒singleton
靜態初始化適合於大多數情形。如果您的應用程式必須延遲例項化、在例項化之前使用非預設的建構函式或執行其他任務、並且工作在多執行緒環境中,那麼您需要另一種解決方案。但是,在一些情況下,您無法像在
"靜態初始化
"示例中那樣依賴公共語言執行庫來確保執行緒的安全性。在這種情況下,必須使用特定的語言功能來確保在存在多執行緒的情況下僅建立乙個物件例項。更常見的解決方案之一是使用
double-check locking
[lea99]
技術來阻止不同的執行緒同時建立
singleton
的新例項。
下面的實現僅允許乙個執行緒在尚未建立singleton
例項的情況下進入關鍵區域(該區域由lock
塊標識)。
public sealed class singleton
?? public static singleton instance
???????? }
???????? return instance;
??????}
?? }
?? private static volatile singleton instance;
?? private static object syncroot = new object();
} //class singleton
此方法確保了僅在需要例項時才會建立僅乙個例項。此外,變數被宣告為volatile,以確保只有在例項變數分配完成後才能訪問例項變數。最後,此方法使用
syncroot
例項來進行鎖定(而不是鎖定型別本身,具體原因請參考切忽鎖定類形物件),以避免發生死鎖。
此double-check locking方法解決了執行緒併發問題,同時避免在每個
instance
屬性方法的呼叫中都出現獨佔鎖定。它還允許您將例項化延遲到第一次訪問物件時發生。實際上,應用程式很少需要這種型別的實現。大多數情況下,靜態初始化方法已經夠用。
-- 摘自msdn? 《使用microsoft .net的企業解決方案模式》一文中的singleton模式
單例項模式 Singleton
單例項模式 singleton 最近乙個人好無聊想寫點東西,正好剛學了點設計模式,覺得singleton這個詞最能引起我的共鳴 single乙個人,ton好多人,街道上人潮襯托我的孤單,想象,誰幸運陪在你身旁,卻誤會一場,你也在等你手機響 暈了,閒話少說,步入正題。建立singleton模式的目的是...
單例項Singleton設計模式
單例項singleton設計模式 這個設計模式主要目的是想在整個系統中只能出現乙個類的例項。這樣做當然是有必然的,比如你的軟體的全域性配置資訊,或者是乙個factory,或是乙個主控類,等等。你希望這 個類在整個系統中只能出現乙個例項。singleton的版本1.0 public class sin...
設計模式之單例項模式 Singleton
原理 將類的建構函式由pubic變為private或者protect,新增獲取物件的public 成員函式,返回指向物件的靜態指標。首先來一段簡單的 實現 一class singleton return pinstance protected singleton private static sin...