程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> 設計模式Singleton

設計模式Singleton

編輯:關於C語言
引言
相信大多數拜讀過"Gang Of Four"(Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides)的經典之作《Design Pattern》的同僚們,對這本書一定推崇有加。曾有人這麼宣告:"只有在讀過《Design Pattern》後,我的編程水平才真正得到了質的飛躍。"

那麼,如何才能步入設計模式的殿堂?設計模式是資深程序員日積月累總結出來的一套可復用的、針對面向對象軟件設計的解決方案,從這個意義上說,世界上存在無數多的設計模式,"Gang Of Four"總結的23種設計模式只是其中的23個精華。入手的關鍵就在於領會"設計模式"的思想,然後再將它們融會貫通、靈活應用到自己到開發過程中。

--------------------------------------------------------------------------------

Singleton模式
Singleton可以說是《Design Pattern》中最簡單也最實用的一個設計模式。那麼,什麼是Singleton?

顧名思義,Singleton就是確保一個類只有唯一的一個實例。Singleton主要用於對象的創建,這意味著,如果某個類采用了Singleton模式,則在這個類被創建後,它將有且僅有一個實例可供訪問。很多時候我們都會需要Singleton模式,最常見的比如我們希望整個應用程序中只有一個連接數據庫的Connection實例;又比如要求一個應用程序中只存在某個用戶數據結構的唯一實例。我們都可以通過應用Singleton模式達到目的。

一眼看去,Singleton似乎有些像全局對象。但是實際上,並不能用全局對象代替Singleton模式,這是因為:其一,大量使用全局對象會使得程序質量降低,而且有些編程語言例如C#,根本就不支持全局變量。其二,全局對象的方法並不能阻止人們將一個類實例化多次:除了類的全局實例外,開發人員仍然可以通過類的構造函數創建類的多個局部實例。而Singleton模式則通過從根本上控制類的創建,將"保證只有一個實例"這個任務交給了類本身,開發人員不可能再有其它途徑得到類的多個實例。這一點是全局對象方法與Singleton模式的根本區別。

--------------------------------------------------------------------------------

Singleton模式的實現
Singleton模式的實現基於兩個要點:

1)不直接用類的構造函數,而另外提供一個Public的靜態方法來構造類的實例。通常這個方法取名為Instance。Public保證了它的全局可見性,靜態方法保證了不會創建出多余的實例。

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》。

--------------------------------------------------------------------------------
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved