你的位置:首页 > ASP.net教程

[ASP.net教程]重构:用Command替换条件调度程序


 

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

 

 

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

提示:责任链模式。