1. 程式人生 > >[翻譯] 單例(Singleton)

[翻譯] 單例(Singleton)

strip ble 不足 做的 時間 不能 att solution 事情

英文原文: https://sourcemaking.com/design_patterns/singleton

意圖

  • 確保一個類只有一個實例,並提供一個訪問其實例的全局點;
  • 封裝 “即時初始化” (just-in-time initialization)或 “首次使用時初始化” (initialization on first use)。

問題

應用需要一個且唯一一個對象的實例。而且,延遲初始化(lazy initialization)和全局訪問是必須的。

討論

使得具有單一實例對象的類負責創建、初始化、訪問和執行。聲明這個實例作為一個私有靜態數據成員。提供一個公共靜態成員函數封裝所有的初始化代碼,同時提供對這個實例的訪問。

任何時候,需要引用單一實例時,客戶端(使用類名和範圍精度操作符1)調用 accessor 函數。

只有滿足所有下面三個標準時,才應該考慮單例模式:

  • 單個實例的所有權不能合理分配;
  • 延遲初始化是可取的;
  • 全局訪問未另行規定;

如果單個成員實例的所有權,何時以及如何初始化,全局訪問都不是問題,那麽單例模式將不足以令人感興趣。

單例模式可以擴展到支持訪問包含大量實例的具體應用。

“靜態成員函數訪問器”(static member function accessor)方法將不會支持 Singleton類的子類。如果需要子類,參考本書中的討論。

刪除一個Singleton類/實例是一個有意義的設計問題。可查看John Vlissides在討論中所說 "To Kill A Singleton" 。

結構

技術分享

使得包含單一實例的類負責訪問和在第一次使用時初始化。這個單一實例是一個私有靜態屬性。而 accessor 函數是一個公共靜態方法。

技術分享

示例

Singleton 模式確保這種類只有一個實例,並提供此實例的全局訪問點。它根據 singleton set 命名,singleton set 定義了一個只包含一個元素的集合。美國總統辦公室就是一個單例。美國憲法指定總統的選舉方式,限制了其任期,並定義了繼任的順序。所以,在任何給定時間,最多只有一個有效的總統。不管這個有效的總統的個人身份,這個標題 “美國總統” 是一個全局訪問點,識別在辦公室的那個人。

技術分享

清單

  1. 在 “單一實例” 類中,定義一個私有靜態屬性。
  2. 在這個類中,定義一個公有靜態 accessor 函數。
  3. 在訪問器(accessor)函數中,進行 “延遲初始化”(在首次使用時創建)。
  4. 定義所有構造體為 protected 或 private 。
  5. 客戶端可能只能使用 accessor 函數來操控 Singleton 。

經驗法則

  • Abstract Factory,Builder 和 Prototype 可以在它們實現中使用 Singleton 。
  • Facade 對象常常是 Singletons,因為其只需要唯一一個 Facade 對象。
  • 狀態對象常常是 Singletons 。
  • Singleton 對於全局變量的優勢是當你使用 Singleton 時,你絕對確信實例的數目,而且你可以改變你的思維和管理任何數量的實例。
  • Singleton 設計模式是最多被不恰當使用的模式之一。Singletons 只有在一個類必須只有一個實例,不能多,也不能少時,才能確定使用。設計者經常錯誤地使用 Singletons 替代全局變量。Singleton 出於意圖和目的是一個全局變量。Singleton 並沒有消除全局變量,它只是對其重命名。
  • 什麽時候 Singleton 是不必要的?簡短的答案:大多數時候。長答案:當以引用的方式傳遞一個對象資源給需要它的對象更容易的時候,而不是讓對象全局訪問資源。對於 Singletons,真正的問題是它們給你一個好借口,不要仔細考慮一個對象的合適的可見性。發現在公開和保護對象之間合適的平衡,對於維護靈活性是非常重要的。

因為我們組有使用全局變量的壞習慣,所以我組織了關於 Singleton 的學習小組。接下來,我發現 Singletons 到處出現,而與全局變量相關的問題一個都沒有消失。對全局數據的問題的答案並不是把它變成 Singleton 。其答案是 “到底你們為什麽使用全局變量?” 改變名字不能改變問題。實際上,這樣,可能會使情況變壞,因為你有機會說,“哦,我沒有那樣做,我是這樣做的” —— 即使這樣和那樣是同一個事情。

代碼示例

Java Singleton in Java Singleton in Java
C++ Singleton in C++: Before and after Singleton in C++
PHP Singleton in PHP
Delphi Singleton in Delphi
Python Singleton in Python

譯者註:

1、範圍精度操作符 - scope resolution operator,即 "::"

[翻譯] 單例(Singleton)