標籤:字串 方法 methods getc 字典 原則 改善 品質 就是
建議149:使用表驅動法避免過長的if和switch分支
隨著代碼變得複雜,我們很容易被過長的if和switch分支困擾。
一個類枚舉類型Week如下:
enum Week { Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday }
如果要把Week的元素值用中文輸出,簡單而醜陋的方法也許是封裝一個GetChineseWeek方法:
static string GetChineseWeek(Week week) { switch (week) { case Week.Monday: return "星期一"; case Week.Tuesday: return "星期二"; case Week.Wednesday: return "星期三"; case Week.Thursday: return "星期四"; case Week.Friday: return "星期五"; case Week.Saturday: return "星期六"; case Week.Sunday: return "星期日"; default: throw new ArgumentOutOfRangeException("week","星期值超出範圍"); } }
之所以說這種方法太醜陋,是因為:
1)分支太長了,而且出現了重複代碼。
2)不利於擴充。如果出現星期八、星期九怎麼辦?當然,星期制已經是固定的了,應該不會出現擴充情況。但是,換種情景來考慮,假設我們正在渲染動畫怎麼辦?誰知道下一秒美工會提交我多少個動畫呢?
一種解決方案是使用多態,它很好的符合了“開閉”原則。如果增加條件分支,不必修改原始碼,直接增加子類就可以了。利用多態避免分支,這裡暫且不表,本建議要採用的是“表驅動法”。
可以把表驅動簡單理解為查字典。代碼如下表示:
static string GetChineseWeek(Week week) { string[] chineseWeek = { "星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日" }; return chineseWeek[(int) week]; } static void Main(string[] args) { Console.WriteLine(GetChineseWeek(Week.Friday)); }
這是一種按照索引值驅動的表驅動法。枚舉元素代表的整型值,很容易和字串數組索引結合起來,用兩行語句就解決了GetChineseWeek方法。但是,這種方法有局限性,如果需要換成:星期一Mike打掃衛生、星期二Rose清理衣櫃、星期三Mike和Rose沒事可以吵吵架、星期四Rose要去Shopping,也就是說需求由靜態屬性變成了動態行為,那麼事情就變得複雜了。
遇上這種情況,我們可能會想到使用多態,在這裡依然使用表驅動法加上一點反射來實現這類動態行為,代碼如下:
class Program { static string ActionInTable(Week week) { string[] methods = { "Cleaning", "CleanCloset", "Quarrel", "Shopping", "Temp", "Temp", "Temp" }; return methods[(int)week]; } static void Main(string[] args) { SampleClass sample=new SampleClass(); var addMethod = typeof (SampleClass).GetMethod(ActionInTable(Week.Monday)); addMethod.Invoke(sample, null); } } class SampleClass { public void Cleaning() { Console.WriteLine("打掃"); } public void CleanCloset() { Console.WriteLine("整理衣櫥"); } public void Quarrel() { Console.WriteLine("吵架"); } public void Shopping() { Console.WriteLine("購物"); } public void Temp() { Console.WriteLine("臨時安排"); } }
表驅動法是一種設計思路,也可以稱為模式。在實際編碼中,不應局限於用索引去驅動行為,而應當根據實際情況靈活運用。
轉自:《編寫高品質代碼改善C#程式的157個建議》陸敏技
【轉】編寫高品質代碼改善C#程式的157個建議——建議149:使用表驅動法避免過長的if和switch分支