泛型 + Singleton Patterns

聽起來 singleton 跟 generic 好像搭不上邊, 不過搭配 .net framework 2.0 的 generic 機制, 倒是可以讓 singleton 好做很多... 我先簡單寫一下不使用 generic 時的做法...

只有單一 class 要實作 singleton 很簡單, 只要寫這樣的 code 就可以:

    7     public class SampleSingletonClass

    8     {

    9         private static SampleSingletonClass _instance = null;

   10         public static SampleSingletonClass Instance

   11         {

   12             get

   13             {

   14                 if (_instance == null)

   15                 {

   16                     _instance = new SampleSingletonClass();

   17                 }

   18 

   19                 return _instance;

   20             }

   21         }

   22 

   23         private SampleSingletonClass()

   24         {

   25             //

   26             //  ToDo: constructor code here.

   27             //

   28         }

   29     }

 很標準的 code, 不是嗎? 不過問題來了... 當我有第二個 class 也要套用 singleton patterns 時, 幾乎一樣的 code 就得再抄一次, 只因為 public static XXX Instance; 這個 static property 的型別不一樣, 很討厭...

這堆看起來差不多的 code 想要省掉, 那只好動點手腳, 用繼承的技術解決, 不過問題又來了, 型別的宣告... 就像一堆 Collection 物件一樣, 傳回型別宣告為 object 就好了, 不過這樣的 code 用起來實在麻煩... 寫起來就像這樣:

    8     public class SingletonBase

    9     {

   10         public static SingletonBase Instance(Type seed)

   11         {

   12             if (_singleton_storage[seed] == null)

   13             {

   14                 _singleton_storage[seed] = Activator.CreateInstance(seed);

   15             }

   16 

   17             return _singleton_storage[seed] as SingletonBase;

   18         }

   19 

   20         private static Hashtable _singleton_storage = new Hashtable();

   21     }

   22 

   23     public class SingletonBaseImpl1 : SingletonBase

   24     {

   25         public SingletonBaseImpl1()

   26             : base()

   27         {

   28             Console.WriteLine("SingletonBaseImpl1.ctor() called.");

   29         }

   30     }

   31 

   32     public class SingletonBaseImpl2 : SingletonBase

   33     {

   34         public SingletonBaseImpl2()

   35             : base()

   36         {

   37             Console.WriteLine("SingletonBaseImpl2.ctor() called.");

   38         }

   39     }

看來不怎麼漂亮? 不過看在重複的 code 只寫一次就好的份上, 醜一點關起門來就看不到了. 不過這樣就沒事了? 不... 用起來更醜... [:'(]

   11             SingletonBase.Instance(typeof(SingletonBaseImpl1));

   12             SingletonBase.Instance(typeof(SingletonBaseImpl1));

   13             SingletonBase.Instance(typeof(SingletonBaseImpl1));

   14 

   15             SingletonBase.Instance(typeof(SingletonBaseImpl2));

   16             SingletonBase.Instance(typeof(SingletonBaseImpl2));

   17             SingletonBase.Instance(typeof(SingletonBaseImpl2));

 

實在無法接受這種 quality 的 "class library" ... 這種 code 看起來一點美感都沒有, 就像文筆不好的人在寫文章一樣...

處女座的個性, 實在不能容忍這種 code 出現在我的 project 裡... 碰到這種問題, 直覺的解決辦法就是:

  1. 透過 inherence, 把這些重複的 code 集中到 super class 一次解決
  2. 同樣邏輯, 要套用到不同型別的應用, 就用 generic 的方式處理

不過要實作還沒那麼簡單, 試了半天, 總算找出一種看起來最得意的解法... <待續>






Facebook Pages

Edit Post (Pull Request)

Post Directory