Singleton

發佈日期 : 4/1/2004 | 更新日期 : 4/1/2004

Singleton

版本: 1.0.1

*
本頁內容

上下文上下文
問題問題
影響因素影響因素
解決方案解決方案
示例示例
結果上下文結果上下文
相關模式相關模式
致謝致謝

上下文

在某些情況下,特定類型的數據需要提供給應用程序中的其他所有對象使用。在大多數情況下,這種類型的數據在系統中還是唯一的。例如,用戶界面只能有一個所有應用程序必須訪問的鼠標指針。同樣,企業解決方案可能用單網關對象作爲接口來管理與特定舊系統的連接。

問題

如何使對象實例全局可用,並保證僅創建一個此類的實例?

注意:相對 Design Patterns: Elements of Reusable Object-Oriented Software [Gamma95] 中的相關定義,此處特意縮小了 singleton 的定義。

影響因素

以下因素影響這種情況中的系統,在考慮上述問題的解決方案時必須協調這些影響因素:

  • 很多編程語言(例如 Microsoft Visual Basic® 6.0 版或 C++)都支持全局對象的定義。這些對象位於命名空間的根部,應用程序中所有對象都可全局使用這些對象。此方法爲全局可訪問性問題提供了一個簡單的解決方案,但是不能解決單實例要求。它無法禁止其他對象創建全局對象的其他實例。另外,其他面向對象的語言(例如 Visual Basic .NET 或 C#)不直接支持全局變量。

  • 要確保某類僅有一個實例,則必須控制實例化過程。因此需要通過使用編程語言中的固有實例化機制(例如通過使用 new 運算符)來阻止其他對象創建該類的實例。控制實例化的另一方面是提供集中機制,所有對象都可通過該機制獲得對此單個實例的引用。

解決方案

Singleton 通過下列方法提供唯一的全局實例:

  • 讓類創建自己的唯一實例。

  • 允許其他對象通過可返回實例引用的類方法來訪問此實例。類方法是全局可訪問的。

  • 將類構造函數聲明爲私有,從而任何其他對象都不能創建新實例。

圖 1 顯示了該模式的靜態結構。UML 類圖表非常簡單,這是因爲 Singleton 由一個簡單類組成,而該類包含了對其自身的單個實例的引用。

圖 1:Singleton 結構

圖 1 顯示,Singleton 類包含了公用類作用範圍(靜態)屬性,該屬性會返回對 Singleton 類的單個實例的引用。(UML 中的下劃線表示類作用範圍屬性。)另外,右上角的數字 1 表示任何時候在系統中該類只能有一個實例。因爲 Singleton 的默認構造函數是私有的,因此係統中的任何其他對象都必須通過 Instance 屬性才能訪問 Singleton 對象。

通常將 Singleton 模式歸類爲慣用語,而不是模式,這是因爲該解決方案主要取決於所用編程語言的功能(例如類方法和靜態初始值)。正如該模式集合所做的那樣,將抽象的概念與特定的實現分隔開來可能會使 Singleton 實現看起來非常簡單。

示例

有關示例請參閱在 C# 語言中實現 Singleton

結果上下文

Singleton 會導致下列優缺點:

優點

  • 實例控制 。 Singleton 會阻止其他對象實例化其自己的 Singleton 對象的副本,從而確保所有對象都訪問唯一實例。

  • 靈活性。因爲類控制了實例化過程,所以類可以靈活更改實例化過程。

缺點

  • 開銷。雖然數量很少,但如果每次對象請求引用時都要檢查是否存在類的實例,將仍然需要一些開銷。可以通過使用靜態初始化解決此問題,相關敘述請參閱"在 C# 中實現 Singleton"。

  • 可能的開發混淆。使用 singleton 對象(尤其在類庫中定義的對象)時,開發人員必須記住自己不能使用 new 關鍵字實例化對象。因爲可能無法訪問庫源代碼,因此應用程序開發人員可能會意外發現自己無法直接實例化此類。

  • 對象生存期。 Singleton 不能解決刪除單個對象的問題。在提供內存管理的語言中(例如基於 .NET Framework 的語言),只有 Singleton 類能夠導致實例被取消分配,因爲它包含對該實例的私有引用。在某些語言中(如 C++),其他類可以刪除對象實例,但這樣會導致 Singleton 類中出現懸浮引用。

相關模式

有關詳細信息,請參閱以下相關模式:

  • Abstract Factory [Gamma95]。在很多情況下,Abstract Factories 是作爲 singleton 實現的。通常情況下,工廠應該能夠被全局訪問。將工廠限制到單個實例可確保一個工廠對創建對象進行全局控制。如果工廠從對象池中分配對象實例,則這樣很有用處。

  • Monostate [Martin02]。Monostate Singleton 相似,但它側重於狀態而不是身份。Monostate 不控制對象實例,而通過聲明所有數據成員是靜態的,從而確保所有實例僅存在一個共享狀態。

  • 使用服務器激活對象通過 .NET Remoting 實現 Broker。此模式使用 Singleton 工廠在服務器上創建新對象。

致謝

[Gamma95] Gamma, Helm, Johnson, and Vlissides. Design Patterns: Elements of Reusable Object-Oriented Software. Addison-Wesley, 1995.

[Martin02] Martin, Robert C. Agile Software Development: Principles, Patterns, and Practices. Prentice Hall, 2002.


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章