当前位置: 代码迷 >> .NET相关 >> 复建:用Command替换条件调度程序
  详细解决方案

复建:用Command替换条件调度程序

热度:163   发布时间:2016-04-24 02:54:03.0
重构:用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()        {        }    }

 

 

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

提示:责任链模式。

 

  相关解决方案