單件模式是一種用於確保整個應用程式中只有一個類實例且這個實例所占資源在整個應用程式中是共享時的程式設計方法(根據實際情況,可能需要幾個類實例)。在某些情況下,這種程式設計方法是很有用處的。
基本介紹
- 中文名:單件模式
- 外文名:singleton
- 隸屬:設計模式
- 學科:計算機學
設計模式,模式實現,
設計模式
單件模式應該使用在什麼場合
當需要控制一個類的實例數量且調用者可以從一個公共的訪問點訪問時。
單件模式類的創建
Singleton模式
Singleton可以說是《Design Pattern》中最簡單也最實用的一個設計模式。那么,什麼是Singleton?
顧名思義,Singleton就是確保一個類只有唯一的一個實例。Singleton主要用於對象的創建,這意味著,如果某個類採用了Singleton模式,則在這個類被創建後,它將有且僅有一個實例可供訪問。很多時候我們都會需要Singleton模式,最常見的比如我們希望整個應用程式中只有一個連線資料庫的Connection實例;又比如要求一個應用程式中只存在某個用戶數據結構的唯一實例。我們都可以通過套用Singleton模式達到目的。
一眼看去,Singleton似乎有些像全局對象。但是實際上,並不能用全局對象代替Singleton模式,這是因為:其一,大量使用全局對象會使得程式質量降低,而且有些程式語言例如C#,根本就不支持全局變數。其二,全局對象的方法並不能阻止人們將一個類實例化多次:除了類的全局實例外,開發人員仍然可以通過類的構造函式創建類的多個局部實例。而Singleton模式則通過從根本上控制類的創建,將"保證只有一個實例"這個任務交給了類本身,開發人員不可能再有其它途徑得到類的多個實例。這一點是全局對象方法與Singleton模式的根本區別。
模式實現
Singleton模式的實現基於兩個要點:
2)將類的構造函式設為Private,即將構造函式"隱藏"起來,任何企圖使用構造函式創建實例的方法都將報錯。這樣就阻止了開發人員繞過上面的Instance方法直接創建類的實例。
通過以上兩點就可以完全控制類的創建:無論有多少地方需要用到這個類,它們訪問的都是類的唯一生成的那個實例。以下C#代碼展現了兩種實現Singleton模式的方式,開發人員可以根據喜好任選其一。
實現方式一:Singleton.cs
using System;
class SingletonDemo
{ private static SingletonDemo theSingleton = null;
private SingletonDemo() {}
public static SingletonDemo Instance()
{ if (null == theSingleton)
{
theSingleton = new SingletonDemo();
}
return theSingleton;
}
static void Main(string[] args)
{ SingletonDemo s1 = SingletonDemo.Instance();
SingletonDemo s2 = SingletonDemo.Instance();
if (s1.Equals(s2))
{ Console.WriteLine("see, only one instance!");
}
}
}
與之等價的另外一種實現方式是:Singleton.cs:
using System;
class SingletonDemo
{ private static SingletonDemo theSingleton = new SingletonDemo();
private SingletonDemo() {}
public static SingletonDemo Instance()
{ return theSingleton;
}
static void Main(string[] args)
{ SingletonDemo s1 = SingletonDemo.Instance();
SingletonDemo s2 = SingletonDemo.Instance();
if (s1.Equals(s2))
{ Console.WriteLine("see, only one instance!");
}
}
}
編譯執行:
Csc Singleton.cs
得到運行結果:
see, only one instance!
.NET中的Singleton
因為Singleton模式具有這樣實用的價值,開發人員除了可以在程式代碼中直接使用Singleton模式外,在許多大型系統的實現上也都處處可見它的影子。在微軟隆重推出的.NET框架中,同樣也可以發現Singleton思想閃爍的光芒。
舉例來說,在.NET框架的重要組成部分Remoting中,遠程對象(Remote Object)有兩種激活方式:伺服器端激活方式和客戶端激活方式。採用伺服器端激活方式的對象又分為兩種類型:Singleton對象和SingleCall對象。Singleton 對象是這樣的對象:無論該對象有多少個客戶端調用,它總是只有一個實例,由這個實例來處理所有的客戶端請求。相反地,若將遠程對象聲明為 SingleCall,則系統會為每次客戶端方法的調用創建一個新對象,即使這些方法調用來自同一個客戶端,也即,對象只在方法調用持續期間存在,一旦方法調用結束,該對象就會被銷毀。顯而易見,這裡的Singleton對象就是設計模式Singleton思想在.NET中的套用。
那么,如何在.NET的Remoting中利用Singleton?.NET提供了兩種方式將一個遠程對象註冊為Singleton:直接調用RegisterWellKnownServiceType方法,在參數中指定對象類型為Singleton;或在配置檔案web.config中設定遠程對象的類型為Singleton。這兩種方法的效果相同,所不同的是後一種方法顯得更加方便,因為改變配置檔案的內容後,不必重新編譯應用程式。下列代碼顯示了如何使用RegisterWellKnownServiceType方法註冊遠程對象類型:
RemotingConfiguration.RegisterWellKnownServiceType( Type.GetType("RemotingSamples.HelloServer,object"), "SayHello", WellKnownObjectMode.Singleton);
參數"SayHello"是客戶端訪問遠程對象(這裡是HelloServer)時用來代表遠程對象的URI,例如tcp://localhost:8085/SayHello(假設使用的是TCP通道)。
最後一個參數就指明了這個遠程對象是Singleton類型。一旦將遠程對象註冊為Singleton,則在第一次客戶端調用HelloServer的方法時創建這個遠程對象,然後保持它直到客戶端中斷連線或對象逾時被銷毀為止。在此期間,無論有多少個客戶端調用這個遠處對象,所有的客戶請求都將由那個已經存在的唯一實例接受處理。
這就是Singleton在.NET中的套用。
從Singleton模式的實現和套用中也可以看出,優秀的設計模式往往都具有"簡約之美"。它們採用一種"優雅"的方式,將那些成功的設計方法和體系結構能夠得以被簡單、方便地復用。這也是為什麼現在的軟體開發日益強調"設計模式"的原因之所在。如果想進一步了解更多的設計模式,還是推薦各位閱讀Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides的經典之作《Design Pattern》