2013年11月8日 星期五

C# Design Pattern - Singleton Pattern 獨體模式

Design PatternJava領域之中己經行之有年,記得我剛接觸這樣的設計時,還是任職遊戲開發時,同事們相互分享的技術,那時候在國外,設計模式已經是一種標準,當然我其實在這領域中,還算是相當的淺,後期在開發遊戲Server之後,因為用的是Java,所以也慢慢的走向這樣的設計。
C#Java物件導向的特性,和C/C++的執行效能,運用在Design Pattern的設計結構,能充份發揮C#的特性。


談論Design Pattern時,我們談論程式產生的「需求」,程式裡有一種類別設計模式,必須保證它們在系統中只存在一個實例,才能確保它們的邏輯正確性、以及良好的效率。

以下是「需求的範例」:

class SingleThread_Singleton
{
    private static SingleThread_Singleton instance = null;
    private SingleThread_Singleton() { }
    public static SingleThread_Singleton Instance
    {
        get
        {
            if (instance == null)
            {
                instance = new SingleThread_Singleton();
            }
            return instance;
        }
    }

}

上面的語法在Sngle-Thread情況當然看似正常執行沒問題,但是在Multi-Thread的情況下卻會出現錯誤的情況。
如兩個Thread同時運行到 if (instance == null)判斷是否被實體化,一個Thread判斷為True後,在產生
SingleThread_Singleton之前,另一個線程也判斷(instance == null),結果也為True

這樣就違背了Singleton模式的原則,一個類別只有一個實例:
class MultiThread_Singleton
{
    private static volatile MultiThread_Singleton instance = null;
    private static object lockHelper = new object();
    private MultiThread_Singleton() { }
    public static MultiThread_Singleton Instance
    {
        get
        {
            if (instance == null)
            {
                lock (lockHelper)
                {
                    if (instance == null)
                    {
                        instance = new MultiThread_Singleton();
                    }
                }
            }
            return instance;
        }
    }

}

這樣的程式結構就能在Multi-Thread情況下實現Singleton
當然上述是以Dynamic方式呈現,如果要用Static的方,可以改寫下列的方式:

class Static_Singleton
{
    public static readonly Static_Singleton instance;
    static Static_Singleton()
    {
        instance = new Static_Singleton();
    }
    private Static_Singleton() { }


}

這樣的設計結構,效果是一樣的,唯一不同的是,是記憶體的配置,Static在程式裡的生命週期是只有當程式結束執行,才會移除,這是要注意的地方。

-雲遊山水為知已逍遙一生而忘齡- 電腦神手

沒有留言:

張貼留言