最近幾天每天都在寫 C#,寫的是某個自己要用的程式,由於只是自己用的,就只求速成,沒有花太多精神在設計上,直到這兩天才感覺到這樣不行,我實在重複了太多次相同的程式,因此決定改寫。
要描述我的需求太麻煩,直接看 code!我理想中的介面是長這樣:
Console.WriteLine(English.Hello());
Console.WriteLine(Chinese.Hello());
Console.WriteLine(Japanese.Hello());
Console.WriteLine(French.Hello());
- 上面的
English、Chinese、Japanese、French都是 subclass,Hello()是 static method,所以不需要實例就能直接呼叫,呼叫了之後就會回傳各國語言的 Hello。 - 同時我希望上述這些 subclass 只要繼承某個 class,就能有一個預設的
Hello(),當有必要時我再 override 這個 method。
起初我是朝 Singleton 的方向研究,由於我想要的是透過繼承,讓 subclass 輕鬆成為 Singleton,所以我應該用 Registry of Singletons。但是我實作出來後,發現我還是得在每個 subclass 複製貼上相同的 code,要不然就是呼叫方式會變成像 English.Instance.Hello() 這般冗贅。有關 C# 如何實做 Registry of Singletons,請參考這篇:The Quest for the Generic Singleton in C#1。
我現在實際作出的介面是長這樣:
Console.WriteLine(Say<English>.Hello());
Console.WriteLine(Say<Japanese>.Hello());
Console.WriteLine(Say<Chinese>.Hello());
Console.WriteLine(Say<French>.Hello());
雖然還沒達到理想,但我覺得不錯了。整個實作如下:
namespace Speaking
{
// 介面
interface ILanguage
{
string Hello();
}
// 基底類別,加上 abstract 是為了避免它被實例化
abstract class DefaultLanguage : ILanguage
{
public virtual string Hello()
{
return "Hello!";
}
}
// 呼叫用的類別
static class Say<TLanguage> where TLanguage : ILanguage, new()
{
private static TLanguage instance;
public static TLanguage Language
{
get
{
// 這裡有點像 Registry of Singletons
// 但我不需要 Registry 就能管理多個 Singletons
// 我也覺得很奇妙 XD
if (instance == null)
{
instance = new TLanguage();
}
return instance;
}
}
// 這才是上面範例中呼叫到的 Hello()
public static string Hello()
{
return Language.Hello();
}
}
// 以下是幾個子類別
class English : DefaultLanguage
{
// 一切都照基底類別,所以我什麼都不用寫
// 附帶一提,這裡不可以寫 private constructor
}
class Chinese : DefaultLanguage
{
// 繼承基底類別,並且 override
public override string Hello()
{
return "你好!";
}
}
class Japanese : ILanguage
{
// 也可以只實作 ILanguage 介面,不繼承基底類別
public string Hello()
{
return "こんにちは!";
}
}
class French : DefaultLanguage, ILanguage
{
// 也可以繼承、實作一起來,其實這個跟只有繼承是一樣的
public override string Hello()
{
return "Bonjour!";
}
}
}
這個方法有個毛病,那些子類別還是可以建立實例,所以不能保證 Singleton。
// 這樣寫的話,就會產生一個新的 English 物件
ILanguage en = new English();
-
這篇文章的標題寫得就像要在 C# 中實作 Singleton 是個天大的謎似的 XD ↩
Gravatar
Author
Joel LeeDate
March 24, 2009Time
4:01 am