赞
踩
由于在业务处理上使用了较多的 switch case 或者 if else,使用了策略模式改造下代码,以便后续的扩展,
但不应为了设计模式而设计模式,应从具体业务出发,不然只会让代码的复杂度增加
也叫 政策模式(Policy Pattern)。指的是对象具备某个行为,但是在不同的场景中,该行为有不同的实现算法。比如一个人的交税比率与他的工资有关,不同的工资水平对应不同的税率。
策略模式使用的就是面向对象的继承和多态机制,从而实现同一行为在不同场景下具备不同实现。
策略模式本质:分离算法,选择实现
1)直白写法
- public void DoWork(int taskType)
- {
- switch (taskType)
- {
- case (int)TaskType.上传单价:
- Console.WriteLine("执行上传单价业务");
- break;
- case (int)TaskType.上传工单:
- Console.WriteLine("执行上传工单业务");
- break;
- case (int)TaskType.上传配件:
- Console.WriteLine("执行上传配件业务");
- break;
- case (int)TaskType.上传附件:
- Console.WriteLine("执行上传附件业务");
- break;
- default:
- Console.WriteLine("无效任务类型");
- break;
- }
- }
2)简单策略模式
2.1)创建策略接口类
- /// <summary>
- /// 策略类接口
- /// </summary>
- public interface IStrategy
- {
- void DoStrategyWork();
- }
2.2)创建策略实现类
- public class 上传单价 : IStrategy
- {
- public void DoStrategyWork()
- {
- Console.WriteLine("执行上传单价业务");
- }
- }
2.3)创建对外调用类
- public class User
- {
- public void StartHere(IStrategy strategy)
- {
- strategy.DoStrategyWork();
- }
- }
2.4)调用
new 一般策略写法.User().StartHere(new InstanceFactory<一般策略写法.IStrategy>().CreateInstanceByEnumName(tType));
3)上下文的引入
上下层调用、交互,往往不是固定不变的,比如调用函数的参数变化、增加方法等
3.1)创建策略抽象类(接口也是可以的,具体业务具体分析)
- /// <summary>
- /// 策略类抽象类
- /// </summary>
- public abstract class IStrategy
- {
- public abstract TaskType CommandType { get; }
-
- public abstract void DoStrategyWork(StrategyContext strategyContext);
- }
3.2)创建策略实现类
- public class 上传单价 : IStrategy
- {
- public override TaskType CommandType => TaskType.上传单价;
-
- public override void DoStrategyWork(StrategyContext strategyContext)
- {
- Console.Write("执行上传单价业务 ");
- Console.WriteLine("我是可变参数:" + strategyContext.pars);
- }
- }
3.3)创建上下文类
通过上下文 进行对应策略算法调用,执行具体实现类的算法,同时写携带业务交互参数
- public class StrategyContext
- {
- private IStrategy _strategy;
-
- #region 可变的上下文参数
-
- public string pars { get; set; }
-
- #endregion
-
- public StrategyContext(IStrategy strategy)
- {
- this._strategy = strategy;
- }
-
- public void InvokingStrategy()
- {
- this._strategy.DoStrategyWork(this);
- }
- }
3.4)创建对外调用类
- public class User
- {
- private StrategyContext strategyContext;
-
- public User(TaskType taskType, string pars)
- {
- this.strategyContext = new StrategyContext(new InstanceFactory<IStrategy>().CreateInstanceBySubClass(taskType));
- this.strategyContext.pars = pars;
- }
-
- public void StartHere()
- {
- strategyContext.InvokingStrategy();
- }
- }
3.5)调用
new 上下文策略写法.User(tType, "我是参数").StartHere();
- /// <summary>
- /// 利用反射创建具体策略类,并缓存起来
- /// </summary>
- public class InstanceFactory<T> where T : class
- {
- /// <summary>
- /// 一般处理对象缓存
- /// </summary>
- private static Dictionary<TaskType, T> dicCommands = new Dictionary<TaskType, T>();
-
- /// <summary>
- /// 上下文策略对象缓存
- /// </summary>
- private static Dictionary<TaskType, T> dicContextCommands = new Dictionary<TaskType, T>();
-
- /// <summary>
- /// 根据TaskType 的名称创建类对象
- /// </summary>
- /// <param name="taskType"></param>
- /// <returns></returns>
- public T CreateInstanceByEnumName(TaskType taskType)
- {
- foreach (TaskType cd in Enum.GetValues(typeof(TaskType)))
- {
- if (!dicCommands.Keys.Contains(cd))
- {
- //(基类)Assembly.Load("当前程序集名称").CreateInstance("命名空间.子类名称"));
- T baseCommand = Assembly.Load(typeof(T).Assembly.GetName().Name)
- .CreateInstance((typeof(T).Namespace + "." + cd)) as T;
-
- if (baseCommand != null)
- {
- dicCommands.Add(cd, baseCommand);
- }
- }
-
- }
-
- return dicCommands.FirstOrDefault(c => c.Key == taskType).Value;
- }
-
- /// <summary>
- /// 通过继承关系创建子类
- /// </summary>
- /// <param name="taskType"></param>
- /// <returns></returns>
- public T CreateInstanceBySubClass(TaskType taskType)
- {
- Type objType = typeof(T);
- // 获取此类型所在的程序集
- Assembly assembly = objType.Assembly;
- // 遍历获取此程序集中所有的类
- foreach (Type t in assembly.GetTypes())
- {
- // 是类并且不是抽象类并且继承IBaseCommand
- if (t.IsClass && !t.IsAbstract && t.IsSubclassOf(objType))
- {
- // 创建策略实例类
- T command = Activator.CreateInstance(t) as T;
-
- var key = (TaskType)Enum.Parse(typeof(TaskType), t.GetProperty("CommandType").DeclaringType.Name);
-
- if (command != null && !dicCommands.ContainsKey(key))
- {
- dicContextCommands.Add(key, command);
- }
- }
- }
-
- return dicContextCommands.FirstOrDefault(c => c.Key == taskType).Value;
- }
- }
https://github.com/harrylsp/Strategy
https://my.oschina.net/BreathL/blog/52655
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。