注:该随笔受启发于 《重构与模式》  第七章 第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()
{ }
}

如果 条件表达式 较为复杂呢,那又可以怎样重构?

提示:责任链模式。

重构:用Command替换条件调度程序的更多相关文章

  1. 重构第四天 : 用多态替换条件语句(if else & switch)

    面相对象的一个核心基础就是多态,当你要根据对象类型的不同要做不同的操作的时候,一个好的办法就是采用多态,把算法封装到子类当中去. 重构前代码: public abstract class Custom ...

  2. 重构与模式 (Joshua Kerievsky 著)

    第1章 本书的写作缘由 第2章 重构 第3章 模式 第4章 代码坏味 第5章 模式导向的重构目录 第6章 创建 第7章 简化 第8章 泛化 第9章 保护 第10章 聚集操作 第11章 实用重构 参考文 ...

  3. 如何解决代码中if…else 过多的问题

    前言 if...else 是所有高级编程语言都有的必备功能.但现实中的代码往往存在着过多的 if...else.虽然 if...else 是必须的,但滥用 if...else 会对代码的可读性.可维护 ...

  4. 你还在 if...else?代码这样写才好看!

    前言 if...else 是所有高级编程语言都有的必备功能.但现实中的代码往往存在着过多的 if...else.虽然 if...else 是必须的,但滥用 if...else 会对代码的可读性.可维护 ...

  5. 如何解决代码中if/else 过多的问题

    前言 if...else 是所有高级编程语言都有的必备功能.但现实中的代码往往存在着过多的 if...else.虽然 if...else 是必须的,但滥用 if...else 会对代码的可读性.可维护 ...

  6. 重构与模式(Refactoring to Patterns)-读书笔记

    第一章 ☛过度设计:是指代码的灵活性和复杂性超出所需. 第二章 ☛重构是一种保持行为的转换. 第三章 ☛每一个模式都是由三部分组成的规则,他表达的是某一环境,一个问题以及解决问题的方案之间的关系. ☛ ...

  7. C#重构之道

    定义 重构的定义:在不改变软件可观察行为的前提下,改善其内部结构. 其中,不改变软件行为,是重构最基本的要求.要想真正发挥威力,就必须做到“不需了解软件行为”. 如果一段代码能让你容易了解其行为,说明 ...

  8. 《Code Complete》ch.24 重构

    WHAT? 重构(refactoring),Martin Fowler将其定义为“在不改变软件外部行为的前提下,对其内部结构进行改变,使之更容易理解并便于修改”. WHY? 神话:一个管理很完善的软件 ...

  9. 重构:越来越长的 switch ... case 和 if ... else if ... else

    在代码中,时常有就一类型码(Type Code)而展开的如 switch ... case 或 if ... else if ... else 的条件表达式.随着项目业务逻辑的增加及代码经年累月的修改 ...

随机推荐

  1. 《你必须知道的.NET》读书笔记一:小OO有大智慧

    此篇已收录至<你必须知道的.Net>读书笔记目录贴,点击访问该目录可以获取更多内容. 一.对象  (1)出生:系统首先会在内存中分配一定的存储空间,然后初始化其附加成员,调用构造函数执行初 ...

  2. http学习笔记(四)——HTTP报文

    http报文是在http应用程序之间发送的数据块,这些数据块以一些文本形式的元信息. 请求报文从客户端流入服务器,向服务器请求数据,服务器响应请求,响应报文从服务器流出,回到客户端. 这就构成了一个事 ...

  3. read links July-14

    1)   http://ruby-hacking-guide.github.io/intro.html It has one part to discuss “Technique to read so ...

  4. swift 加载 storyboard 里的UIViewController

    let storyBoard:UIStoryboard! = UIStoryboard(name: "Main", bundle: nil) let deskVC:DeskView ...

  5. 几款开源的图形化Redis客户端管理软件

    转载于:http://www.itxuexiwang.com/a/shujukujishu/redis/2016/0216/98.html?1455870209 Redis是一个超精简的基于内存的键值 ...

  6. Eloquent ORM笔记

    基本操作 新增 $user = new User; $user->name = 'John'; $user->save(); $insertedId = $user->id;//从对 ...

  7. 使用Sublime Text 2 编辑Markdown

    http://www.ituring.com.cn/article/6815 一.安装 下载Sublime Text 2 安装 二.安装Package Control 按Ctrl + ` 打开cons ...

  8. [开发工具]Java开发常用的在线工具

    注明: 本文转自http://www.hollischuang.com/archives/1459.作为一个Java开发人员,经常要和各种各样的工具打交道,除了我们常用的IDE工具以外,其实还有很多工 ...

  9. salesforce 零基础学习(二十六)自定义图表chart简单介绍(使用apex和VF实现)

    chart在报表中经常使用到,他可以使报表结果更加直观的展现给用户.salesforce支持VF和apex代码来更好的展示chart. chart分类:常用的图表样式有饼状图,柱状图,折线图,条形图, ...

  10. CKEditor Html Helpers for ASP.NET MVC3 Razor/WebForms Views

    一.原生方法: 在 razor 中 使用Fckeditor 编辑内容,需要引入js <script src="@Url.Content("~/fckeditor/fckedi ...