注:該隨筆受啓發於 《重構與模式》 第七章 第7.6小節 用Command替換條件調度程序 。ide
對於Command不作過多解釋,這裏我找了兩個例子、供部分園友參閱:Command例子1 Command例子2 。this
條件調度程序:我對這個名詞的理解爲,它是相對簡單的選擇結構 與 相對獨立的業務邏輯的結合體。編碼
話不是很好理解,下面舉個小例子吧。spa
重構前的代碼:.net
/// <summary> /// 很簡單的選擇分支 一層 if else /// N個 相對獨立 任務 /// </summary> /// <param name="actionName"></param> public void DoAction(string actionName) { if (actionName == "Action1") { // 處理 Action1任務 Console.WriteLine("執行任務1"); } else if (actionName == "Action2") { // 處理 Action2任務 Console.WriteLine("執行任務2"); } else if (actionName == "Action3") { // 處理 Action3任務 // 無處理操做 } }
在 《重構與模式》 一文中的重構的作法是:code
爲每個動做建立一個Command,把這些Command存儲在一個集合中, 並用獲取及執行Command的代碼替換條件邏輯。htm
重構步驟我不作詳細描述,看一下重構後的結果吧:blog
public class class2 { private Dictionary<string, CommandAbstract> dic; public class2() { this.dic = new Dictionary<string, CommandAbstract>(); this.dic.Add("Action1", new Command1()); this.dic.Add("Action2", new Command2()); this.dic.Add("Action3", new Command3()); } /// <summary> /// 應用 Command模式 替換 條件調度程序/// </summary> /// <param name="actionName"></param> public void DoAction(string actionName) { CommandAbstract command = null; if (dic.ContainsKey(actionName)) { command = dic[actionName]; } if (command != null) { command.Execute(); } } } public abstract class CommandAbstract { public abstract void Execute(); } public class Command1 : CommandAbstract { public override void Execute() { Console.WriteLine("執行任務1"); } } public class Command2 : CommandAbstract { public override void Execute() { Console.WriteLine("執行任務2"); } } public class Command3 : CommandAbstract { public override void Execute() { } }
看着 硬編碼 Dictionary 很不爽,若是常常須要添加新Command, 有可能還須要繼續重構——使其遵循開閉原則。get
方案:使用反射代替硬編碼 (簡單的Plugin模式),重構後的結果以下:string
public static class CommandFactory { private static Dictionary<string, CommandAbstract> dic; static CommandFactory() { dic = new Dictionary<string, CommandAbstract>(); Type absType = typeof(CommandAbstract); Assembly assem = absType.Assembly; foreach (Type t in assem.GetTypes()) { if (t.IsClass && !t.IsAbstract && t.IsSubclassOf(absType)) { CommandAbstract command = Activator.CreateInstance(t) as CommandAbstract; if (command != null && !dic.ContainsKey(command.CommandName)) { dic.Add(command.CommandName, command); } } } } public static CommandAbstract GetCommand(string commandName) { if (dic.ContainsKey(commandName)) { return dic[commandName]; } return null; } } public class class2 {/// <summary> /// 重構硬編碼/// </summary> /// <param name="actionName"></param> public void DoAction(string actionName) { CommandAbstract command = CommandFactory.GetCommand(actionName); if (command != null) { command.Execute(); } } } public abstract class CommandAbstract { public string CommandName { get; protected set; } public abstract void Execute(); } public class Command1 : CommandAbstract { public Command1() { this.CommandName = "Action1"; } public override void Execute() { Console.WriteLine("執行任務1"); } } public class Command2 : CommandAbstract { public Command2() { this.CommandName = "Action2"; } public override void Execute() { Console.WriteLine("執行任務2"); } } public class Command3 : CommandAbstract { public Command3() { this.CommandName = "Action3"; } public override void Execute() { } }
若是 條件表達式 較爲複雜呢,那又能夠怎樣重構?
提示:責任鏈模式。