
·您现在的位置: 云翼网络 >> 文章中心 >> 网站建设 >> 网站建设开发 >> 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()
{
}
}
如果 条件表达式 较为复杂呢,那又可以怎样重构?
提示:责任链模式。