重构:用Command替换条件调度程序
2018-06-18 02:54:16来源:未知 阅读 ()
注:该随笔受启发于 《重构与模式》 第七章 第7.6小节 用Command替换条件调度程序 。
对于Command不做过多解释,这里我找了两个例子、供部分园友参阅:Command例子1 Command例子2 。
条件调度程序:我对这个名词的理解为,它是相对简单的选择结构 与 相对独立的业务逻辑的结合体。
话不是很好理解,下面举个小例子吧。
重构前的代码:
/// <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任务 // 无处理操作 } }
在 《重构与模式》 一文中的重构的做法是:
为每一个动作创建一个Command,把这些Command存储在一个集合中, 并用获取及执行Command的代码替换条件逻辑。
重构步骤我不做详细描述,看一下重构后的结果吧:
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, 有可能还需要继续重构——使其遵循开闭原则。
方案:使用反射代替硬编码 (简单的Plugin模式),重构后的结果如下:
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() { } }
如果 条件表达式 较为复杂呢,那又可以怎样重构?
提示:责任链模式。
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
上一篇:理解 .NET 2015
- 条款02:尽量以const,enum,inline替换#define 2020-01-12
- Java 操作Word书签(三):用文本、图片、表格替换书签 2019-08-29
- 05 替换空格 2018-11-20
- 洛谷P4197 Peaks(Kruskal重构树 主席树) 2018-09-18
- linux 热替换so文件 2018-09-18
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash