2010-06-03 88 views

回答

22

寧願單身人士超過靜態類(假設你沒有更好的模式;))的一個好理由是將一個單例實例換成另一個。

舉例來說,如果我有一個日誌類是這樣的:

public static class Logger { 
    public static void Log(string s) { ... } 
} 

public class Client { 
    public void DoSomething() { 
     Logger.Log("DoSomething called"); 
    } 
} 

它的作品真的很好,但如果記錄儀寫東西到數據庫,或將輸出寫入到控制檯。如果你正在編寫測試,你可能不需要所有這些副作用 - 但是由於日誌方法是靜態的,除了以外,你不能做任何事情。

好的,所以我想熱插拔我的Log方法進行測試。去小工具單身!

public class Logger { 
    private static Logger _instance; 
    public static Logger Instance 
    { 
     get 
     { 
      if (_instance == null) 
       _instance = new Logger(); 
      return _instance; 
     } 
     set { _instance = value; } 
    } 
    protected Logger() { } 
    public virtual void Log(string s) { ... } 
} 

public class Client { 
    public void DoSomething() { 
     Logger.Instance.Log("DoSomething called"); 
    } 
} 

所以,你可以定義一個空Log方法TestLogger : Logger,然後設置你的測試日誌的實例爲測試的單一實例。普雷斯托!您可以在不影響客戶端代碼的情況下對測試或生產的記錄器實現進行熱插拔。

10

單身通常優於全局變量,因爲:

  • 他們不污染全局命名空間(或者在與命名空間,其含有的命名空間的語言)不必要的變數。
  • 它們允許惰性分配和初始化,而許多語言中的全局變量總是會消耗資源。

Source

編輯:

一種涼爽使用單例中,當與工廠方法相結合,可以用於創建Flyweight pattern。這是當你創建一個新對象時,Factory(而不是創建一個新對象)首先檢查是否已經創建了該對象的單例,如果是,它只是返回該對象,否則創建一個新的單例並返回它,跟蹤它創建的單例。 Flyweights由於單身人員的不變性而工作。

+1

飛錘更像是一個「多例」,不是一個真正的單身。 – BalusC 2010-06-03 20:51:45

+0

Multiton ...我喜歡它! – 2010-06-03 20:53:03

+2

它確實存在。參見[wikipedia](http://en.wikipedia.org/wiki/Multiton_pattern)。 – BalusC 2010-06-03 21:11:25

2

單身保留傳統類的做法,不要求您使用static關鍵字隨處可見。起初他們可能要求更高,但會大大簡化程序的架構。與靜態類不同,我們可以使用單例作爲參數或對象。

此外,您可以像使用其他任何類一樣使用單例接口。

3

即使恕我直言,單例模式是一個相當濫用模式,但它有時會提供的好處,如:

  • 使用不同類型的對象(即從相同的基本繼承)作爲實例的能力(例如,數據提供者使用文件系統,其中一個使用SQL數據庫)
  • 可串行化。我沒有使用可以自動序列化靜態類的框架。
  • 使用較少的靜態字段。對某些人來說,這更多的是審美特徵,但在某些情況下,它具有實際的好處。
5

單身對我來說似乎有點多餘。我更喜歡靜態類,如果我需要不同的行爲,我將它與依賴注入和提供者結合起來..我不知道這是什麼模式,或者它是否有名稱,但它通常是這樣的:

public interface IFooProvider { 
    Bar FooBar(); 
} 

public static class Foo { 
    public static readonly IFooProvider FooProvider { get; set; } 
    public Bar FooBar() { return FooProvider.FooBar(); } 
} 

然後我只是確保在我的init方法中設置提供程序的某處。如果要通過在類初始化時設置默認提供程序來添加延遲初始化,這很容易。最重要的是,它可以讓你改變行爲,同時還能獲得使用靜態類的美感。

1
  1. 一個單可以實現接口,從其他類
  2. 一個singleton可以懶惰地或異步地進行初始化,並且由.NET Framework CLR(公共語言運行時)當包含類別的節目或命名空間是自動加載繼承加載。雖然靜態類通常在初次加載時初始化,並且會導致潛在的類加載器問題。
  3. 單例類遵循面向對象的原則
  4. 單個對象存儲在堆中,而靜態類存儲在堆棧中。
  5. Singleton對象可以有構造函數,而靜態類不能。
  6. 單一對象可配置而不是靜態類
  7. 單一對象可以複製,但不能用靜態類
相關問題