聽起來 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 裡... 碰到這種問題, 直覺的解決辦法就是:
- 透過 inherence, 把這些重複的 code 集中到 super class 一次解決
- 同樣邏輯, 要套用到不同型別的應用, 就用 generic 的方式處理
不過要實作還沒那麼簡單, 試了半天, 總算找出一種看起來最得意的解法... <待續>