注:该随笔受启发于 《重构与模式》 第七章 第7.6小节 用Command替换条件调度程序 。
对于Command不做过多解释,这里我找了两个例子、供部分园友参阅:Command例子1 Command例子2 。
条件调度程序:我对这个名词的理解为,它是相对简单的选择结构 与 相对独立的业务逻辑的结合体。
话不是很好理解,下面举个小例子吧。
重构前的代码:
///<summary>///很简单的选择分支 一层 if else///N个 相对独立 任务///</summary>///<param name="actionName"></param>publicvoidDoAction(stringactionName)
{if(actionName =="Action1")
{//处理 Action1任务Console.WriteLine("执行任务1");
}elseif(actionName =="Action2")
{//处理 Action2任务Console.WriteLine("执行任务2");
}elseif(actionName =="Action3")
{//处理 Action3任务//无处理操作}
}
在 《重构与模式》 一文中的重构的做法是:
为每一个动作创建一个Command,把这些Command存储在一个集合中, 并用获取及执行Command的代码替换条件逻辑。
重构步骤我不做详细描述,看一下重构后的结果吧:
publicclassclass2
{PRivateDictionary<string, CommandAbstract>dic;publicclass2()
{this.dic =newDictionary<string, CommandAbstract>();this.dic.Add("Action1",newCommand1());this.dic.Add("Action2",newCommand2());this.dic.Add("Action3",newCommand3());
}///<summary>/// 应用 Command模式替换 条件调度程序///</summary>///<param name="actionName"></param>publicvoidDoAction(stringactionName)
{
CommandAbstract command=null;if(dic.ContainsKey(actionName))
{
command=dic[actionName];
}if(command !=null)
{
command.Execute();
}
}
}publicabstractclassCommandAbstract
{publicabstractvoidExecute();
}publicclassCommand1 : CommandAbstract
{publicoverridevoidExecute()
{
Console.WriteLine("执行任务1");
}
}publicclassCommand2 : CommandAbstract
{publicoverridevoidExecute()
{
Console.WriteLine("执行任务2");
}
}publicclassCommand3 : CommandAbstract
{publicoverridevoidExecute()
{
}
}
看着 硬编码 Dictionary 很不爽,如果经常需要添加新Command, 有可能还需要继续重构——使其遵循开闭原则。
方案:使用反射代替硬编码 (简单的Plugin模式),重构后的结果如下:
publicstaticclassCommandFactory
{privatestaticDictionary<string, CommandAbstract>dic;staticCommandFactory()
{
dic=newDictionary<string, CommandAbstract>();
Type absType=typeof(CommandAbstract);
Assembly assem=absType.Assembly;foreach(Type tinassem.GetTypes())
{if(t.IsClass && !t.IsAbstract &&t.IsSubclassOf(absType))
{
CommandAbstract command= Activator.CreateInstance(t)asCommandAbstract;if(command !=null&& !dic.ContainsKey(command.CommandName))
{
dic.Add(command.CommandName, command);
}
}
}
}publicstaticCommandAbstract GetCommand(stringcommandName)
{if(dic.ContainsKey(commandName))
{returndic[commandName];
}returnnull;
}
}publicclassclass2
{///<summary>///重构硬编码///</summary>///<param name="actionName"></param>publicvoidDoAction(stringactionName)
{
CommandAbstract command=CommandFactory.GetCommand(actionName);if(command !=null)
{
command.Execute();
}
}
}publicabstractclassCommandAbstract
{publicstringCommandName {get;protectedset; }publicabstractvoidExecute();
}publicclassCommand1 : CommandAbstract
{publicCommand1()
{this.CommandName ="Action1";
}publicoverridevoidExecute()
{
Console.WriteLine("执行任务1");
}
}publicclassCommand2 : CommandAbstract
{publicCommand2()
{this.CommandName ="Action2";
}publicoverridevoidExecute()
{
Console.WriteLine("执行任务2");
}
}publicclassCommand3 : CommandAbstract
{publicCommand3()
{this.CommandName ="Action3";
}publicoverridevoidExecute()
{
}
}
如果 条件表达式 较为复杂呢,那又可以怎样重构?
提示:责任链模式。