• C#使用策略模式或者委托替代多IfElse判断和Switch语句


      这篇文件介绍使用设计模式中的策略模式和委托来解决多个IfElse判断语句和Switch语句,这种替换方式在其他语言也一样可以做到,比如PHP、JavaScript、Python或者Java等。

      这里以C#为例进行演示。

      需要为一个程序编写计算方法,根据标签名称来决定不同的计算,大体意思如下:

    1. if(标签名=="值1"){
    2.   return sum(标签数据,附加标签数据);
    3. }
    4. if(标签名=="值2"){
    5.   return max(标签数据,附加标签数据);
    6. }
    7. if(标签名=="值3"){
    8.   return min(标签数据,附加标签数据);
    9. }
    10. if(标签名=="值4"){
    11.   return 标签数据*blc+附加标签数据;
    12. }
    13. if(标签名=="值5"){
    14.   return 标签数据+附加标签数据*blc;
    15. }
    16. ......
    17. if(标签名=="值21"){
    18.    return 计算方法21
    19. }

      或者使用Switch语句:

    1. switch(标签名){
    2.   case "值1"
    3.     return sum(标签数据,附加标签数据);
    4.     break;
    5.   case "值2"
    6.     return max(标签数据,附加标签数据);
    7.     break;
    8.   case "值3"
    9.     return min(标签数据,附加标签数据);
    10.     break;
    11.   ......
    12.   case "值21"
    13.     return 计算方法21
    14.     break;
    15.   default:
    16.     return 0
    17.     break;
    18. }

      因为设备很多,有很多没有列出的标签,后面可能增加的标签最多的时候有20多种,那么这个地方使用这样的方式就很不合适了。

      需要针对这些代码进行重构

      先使用策略模式进行重构,再使用委托进行更加简明的重构。

      针对这种问题容易想到的是设计模式中的策略模式,策略模式比较简单,我们可以将这部分计算封装在一个DLL文件中,在程序中调用,这样增加算法可以不必须改动主程序代码。

      1、使用策略模式进行改写

      策略模式就是封装算法,让算法独立于客户的使用,一般是在确定算法时直接调用对应的算法,我们可以进行改进,生产一个算法列表供选择。

      主要是策略模式加算法列表,代码如下:

      算法类:

    1. public abstract class YQCYFormula
    2. {
    3. protected List<double> InterListA;
    4. protected List<double> AddonListA;
    5. protected double RatioA;
    6. public string FormulaNameA;
    7. public void SetData(List<double> InterList, List<double> AddonList, double Ratio)
    8. {
    9. this.InterListA = InterList;
    10. this.AddonListA = AddonList;
    11. this.RatioA = Ratio;
    12. }
    13. public abstract double GetResult();
    14. }
    15. public class GetMax:YQCYFormula
    16. {
    17. public GetMax()
    18. {
    19. base.FormulaNameA= "最大值";
    20. }
    21. public override double GetResult()
    22. {
    23. double DResult = (this.InterListA.Union(AddonListA).ToList<double>()).Max();
    24. DResult = Math.Round(DResult, 2);
    25. return DResult;
    26. }
    27. }
    28. public class GetMin : YQCYFormula
    29. {
    30. public GetMin()
    31. {
    32. base.FormulaNameA = "最小值";
    33. }
    34. public override double GetResult()
    35. {
    36. double DResult = (this.InterListA.Union(AddonListA).ToList<double>()).Min();
    37. DResult=Math.Round(DResult,2);
    38. return DResult;
    39. }
    40. }
    41. public class GetSum : YQCYFormula
    42. {
    43. public GetSum()
    44. {
    45. base.FormulaNameA = "总和";
    46. }
    47. public override double GetResult()
    48. {
    49. double DResult = this.InterListA.Sum() + this.AddonListA.Sum();
    50. DResult = Convert.ToDouble(DResult.ToString("#0.00"));
    51. return DResult;
    52. }
    53. }
    54. public class GetAverage : YQCYFormula
    55. {
    56. public GetAverage()
    57. {
    58. base.FormulaNameA = "平均值";
    59. }
    60. public override double GetResult()
    61. {
    62. double DResult = (this.InterListA.Sum() + this.AddonListA.Sum()) / (this.InterListA.Count + this.AddonListA.Count);
    63. DResult = Convert.ToDouble(DResult.ToString("#0.00"));
    64. return DResult;
    65. }
    66. }

      实际应用:

    1. ArrayList DictFormula = new ArrayList();//算法列表
    2. YQCYFormula MyFormula;//算法实例
    3. //注册算法
    4. MyFormula = new GetMax();
    5. DictFormula.Add(MyFormula);
    6. MyFormula = new GetMin();
    7. DictFormula.Add(MyFormula);
    8. MyFormula = new GetSum();
    9. DictFormula.Add(MyFormula);
    10. MyFormula = new GetAverage();
    11. DictFormula.Add(MyFormula);

      使用:

    1. double Ratio = 0.1;
    2. List<double> InterList = new List<double>();
    3. List<double> AddonList = new List<double>();
    4. Ratio = 0.1;
    5. InterList = new List<double> { 1.1, 2.2, 3, 3, 4.4, 5.5 };
    6. AddonList = new List<double> { 1.5, 2.5, 3.5, 4.5 };
    7. textBox1.Text += comboBox1.Text+":"+ GetResult(comboBox1.Text, InterList,AddonList,Ratio).ToString()+Environment.NewLine;

      因为算法是在独立的,这样如果有了新的算法,只需要增加算法并注册,调用程序并不需要改变,结果如下。

      2、使用委托来改写。

      主要使用算法字典和委托进行,代码如下:

      定义算法字典:

            Dictionary<string, FormulaYQCY> DictCalculation = new Dictionary<string, FormulaYQCY>();

      定义算法:

    1. public delegate double FormulaYQCY(List<double> InterList, List<double> AddonList, double Ratio);
    2. public FormulaYQCY MyFormula;
    3. private double FormulaMax(List<double> InterList,List<double> AddonList,double Ratio)
    4. {
    5. double DResult = (InterList.Union(AddonList).ToList<double>()).Max();
    6. DResult = Math.Round(DResult, 2);
    7. return DResult;
    8. }
    9. private double FormulaMin(List<double> InterList, List<double> AddonList,double Ratio)
    10. {
    11. double DResult = (InterList.Union(AddonList).ToList<double>()).Min();
    12. DResult = Math.Round(DResult, 2);
    13. return DResult;
    14. }
    15. private double FormulaSum(List<double> InterList, List<double> AddonList, double Ratio)
    16. {
    17. double DResult = InterList.Sum() + AddonList.Sum();
    18. DResult = Convert.ToDouble(DResult.ToString("#0.00"));
    19. return DResult;
    20. }
    21. private double FormulaAverage(List<double> InterList, List<double> AddonList, double Ratio)
    22. {
    23. double DResult = (InterList.Sum() + AddonList.Sum()) / (InterList.Count + AddonList.Count);
    24. DResult = Convert.ToDouble(DResult.ToString("#0.00"));
    25. return DResult;
    26. }

      注册算法:

    1. MyFormula = FormulaMax;
    2. DictCalculation.Add("最大值", MyFormula);
    3. MyFormula = FormulaMin;
    4. DictCalculation.Add("最小值", MyFormula);
    5. MyFormula = FormulaSum;
    6. DictCalculation.Add("总和", MyFormula);
    7. MyFormula = FormulaAverage;
    8. DictCalculation.Add("平均值", MyFormula);

      使用:

    1. double DoubleReslut = 0.0;
    2. double Ratio = 0.1;
    3. List<double> InterList = new List<double> { 1.1, 2.2, 3, 3, 4.4, 5.5 };
    4. List<double> AddonList = new List<double> { 1.5, 2.5, 3.5, 4.5 };
    5. foreach (var item in DictCalculation)
    6. {
    7. if (item.Key == comboBox1.Text)
    8. {
    9. MyFormula = item.Value as FormulaYQCY;
    10. DoubleReslut = MyFormula(InterList, AddonList, Ratio);
    11. textBox1.Text += comboBox1.Text+":" + DoubleReslut.ToString()+Environment.NewLine;
    12. }
    13. }

      实际输出:

       在实际编写代码过程中,有了字典或者列表,一般情况下我们已经可以不再使用多If...else语句或者Switch语句来进行分支判断输出,代码和程序的灵活性也明显增加了。

  • 相关阅读:
    微信小程序603300报错,保存文件出错download save file error的解决办法
    MQ 之 RoketMQ(下载、安装、快速启动、控制台、集群部署)
    Codeforces Round #813 (Div. 2) A. Wonderful Permutation
    常见遍历方法 for循环、forEach、map、filter、find、findIndex、some、every
    boa交叉编译(移植到arm)
    Spring Boot 发送邮件
    ssm框架之spring:xml如何配置创建对象
    2022-2028全球及中国特殊黄铜棒行业研究及十四五规划分析报告
    Android学习笔记 25. Activity与Fragment通信
    Django初窥门径-自定义用户模型
  • 原文地址:https://blog.csdn.net/dawn0718/article/details/128168162