当前位置:   article > 正文

C# 反射 策略模式改造 switch case 或者 if else_在c#中用什么来替代if. case

在c#中用什么来替代if. case

一、前言

        由于在业务处理上使用了较多的 switch case 或者 if else,使用了策略模式改造下代码,以便后续的扩展,

不应为了设计模式而设计模式,应从具体业务出发,不然只会让代码的复杂度增加

二、何为策略模式

         也叫 政策模式(Policy Pattern)。指的是对象具备某个行为,但是在不同的场景中,该行为有不同的实现算法。比如一个人的交税比率与他的工资有关,不同的工资水平对应不同的税率。

策略模式使用的就是面向对象的继承和多态机制,从而实现同一行为在不同场景下具备不同实现。

策略模式本质:分离算法,选择实现

三、应用策略模式

1)直白写法

  1. public void DoWork(int taskType)
  2. {
  3. switch (taskType)
  4. {
  5. case (int)TaskType.上传单价:
  6. Console.WriteLine("执行上传单价业务");
  7. break;
  8. case (int)TaskType.上传工单:
  9. Console.WriteLine("执行上传工单业务");
  10. break;
  11. case (int)TaskType.上传配件:
  12. Console.WriteLine("执行上传配件业务");
  13. break;
  14. case (int)TaskType.上传附件:
  15. Console.WriteLine("执行上传附件业务");
  16. break;
  17. default:
  18. Console.WriteLine("无效任务类型");
  19. break;
  20. }
  21. }

 2)简单策略模式

截取自  http://my.oschina.net/BreathL/blog/52655

 

2.1)创建策略接口类

  1. /// <summary>
  2. /// 策略类接口
  3. /// </summary>
  4. public interface IStrategy
  5. {
  6. void DoStrategyWork();
  7. }

2.2)创建策略实现类

  1. public class 上传单价 : IStrategy
  2. {
  3. public void DoStrategyWork()
  4. {
  5. Console.WriteLine("执行上传单价业务");
  6. }
  7. }

2.3)创建对外调用类

  1. public class User
  2. {
  3. public void StartHere(IStrategy strategy)
  4. {
  5. strategy.DoStrategyWork();
  6. }
  7. }

2.4)调用

new 一般策略写法.User().StartHere(new InstanceFactory<一般策略写法.IStrategy>().CreateInstanceByEnumName(tType));

3)上下文的引入

上下层调用、交互,往往不是固定不变的,比如调用函数的参数变化、增加方法等

截取自  http://my.oschina.net/BreathL/blog/52655

 

3.1)创建策略抽象类(接口也是可以的,具体业务具体分析)

  1. /// <summary>
  2. /// 策略类抽象类
  3. /// </summary>
  4. public abstract class IStrategy
  5. {
  6. public abstract TaskType CommandType { get; }
  7. public abstract void DoStrategyWork(StrategyContext strategyContext);
  8. }

3.2)创建策略实现类

  1. public class 上传单价 : IStrategy
  2. {
  3. public override TaskType CommandType => TaskType.上传单价;
  4. public override void DoStrategyWork(StrategyContext strategyContext)
  5. {
  6. Console.Write("执行上传单价业务 ");
  7. Console.WriteLine("我是可变参数:" + strategyContext.pars);
  8. }
  9. }

3.3)创建上下文类

通过上下文  进行对应策略算法调用,执行具体实现类的算法,同时写携带业务交互参数

  1. public class StrategyContext
  2. {
  3. private IStrategy _strategy;
  4. #region 可变的上下文参数
  5. public string pars { get; set; }
  6. #endregion
  7. public StrategyContext(IStrategy strategy)
  8. {
  9. this._strategy = strategy;
  10. }
  11. public void InvokingStrategy()
  12. {
  13. this._strategy.DoStrategyWork(this);
  14. }
  15. }

3.4)创建对外调用类

  1. public class User
  2. {
  3. private StrategyContext strategyContext;
  4. public User(TaskType taskType, string pars)
  5. {
  6. this.strategyContext = new StrategyContext(new InstanceFactory<IStrategy>().CreateInstanceBySubClass(taskType));
  7. this.strategyContext.pars = pars;
  8. }
  9. public void StartHere()
  10. {
  11. strategyContext.InvokingStrategy();
  12. }
  13. }

3.5)调用

new 上下文策略写法.User(tType, "我是参数").StartHere();

四、反射创建对象

  1. /// <summary>
  2. /// 利用反射创建具体策略类,并缓存起来
  3. /// </summary>
  4. public class InstanceFactory<T> where T : class
  5. {
  6. /// <summary>
  7. /// 一般处理对象缓存
  8. /// </summary>
  9. private static Dictionary<TaskType, T> dicCommands = new Dictionary<TaskType, T>();
  10. /// <summary>
  11. /// 上下文策略对象缓存
  12. /// </summary>
  13. private static Dictionary<TaskType, T> dicContextCommands = new Dictionary<TaskType, T>();
  14. /// <summary>
  15. /// 根据TaskType 的名称创建类对象
  16. /// </summary>
  17. /// <param name="taskType"></param>
  18. /// <returns></returns>
  19. public T CreateInstanceByEnumName(TaskType taskType)
  20. {
  21. foreach (TaskType cd in Enum.GetValues(typeof(TaskType)))
  22. {
  23. if (!dicCommands.Keys.Contains(cd))
  24. {
  25. //(基类)Assembly.Load("当前程序集名称").CreateInstance("命名空间.子类名称"));
  26. T baseCommand = Assembly.Load(typeof(T).Assembly.GetName().Name)
  27. .CreateInstance((typeof(T).Namespace + "." + cd)) as T;
  28. if (baseCommand != null)
  29. {
  30. dicCommands.Add(cd, baseCommand);
  31. }
  32. }
  33. }
  34. return dicCommands.FirstOrDefault(c => c.Key == taskType).Value;
  35. }
  36. /// <summary>
  37. /// 通过继承关系创建子类
  38. /// </summary>
  39. /// <param name="taskType"></param>
  40. /// <returns></returns>
  41. public T CreateInstanceBySubClass(TaskType taskType)
  42. {
  43. Type objType = typeof(T);
  44. // 获取此类型所在的程序集
  45. Assembly assembly = objType.Assembly;
  46. // 遍历获取此程序集中所有的类
  47. foreach (Type t in assembly.GetTypes())
  48. {
  49. // 是类并且不是抽象类并且继承IBaseCommand
  50. if (t.IsClass && !t.IsAbstract && t.IsSubclassOf(objType))
  51. {
  52. // 创建策略实例类
  53. T command = Activator.CreateInstance(t) as T;
  54. var key = (TaskType)Enum.Parse(typeof(TaskType), t.GetProperty("CommandType").DeclaringType.Name);
  55. if (command != null && !dicCommands.ContainsKey(key))
  56. {
  57. dicContextCommands.Add(key, command);
  58. }
  59. }
  60. }
  61. return dicContextCommands.FirstOrDefault(c => c.Key == taskType).Value;
  62. }
  63. }

五、代码下载

https://github.com/harrylsp/Strategy

六、参考引用

https://my.oschina.net/BreathL/blog/52655

https://blog.csdn.net/qq_19348391/article/details/84404034

https://blog.csdn.net/site008/article/details/77947566

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/142211
推荐阅读
相关标签
  

闽ICP备14008679号