业务流程:
1.用户根据需要选择的实验方案,每个实验方案对应一种计算公式,计算公式例如下面这种
2.将带有实验数据的PDF文件上传到特定位置,对PDF文件进行解析后将数据数据保存到数据库。
3.遍历所有方案,对每种方案使用特定的公式对数据库中的数据进行
重构前实现:
遍历方案,使用IF语句对使用的公式进行判断,而后在IF块里对数据进行处理
IF(Formula=='F1'){
//F1的处理...
}
IF(Formula=='F2'){
//F2的处理...
}
IF(Formula=='F3'){
//F2的处理...
}
这样实现的问题就是程序太过庞大,八十多个公式就要有八十多个判断语句,并且判断内部的处理现也是很庞大的,这就导致了这个程序可读性很差,维护以及调试都十分困难。
重构
这里考虑使用策略模式+简单工厂进行重构
策略模式(Strategy Pattern):定义一系列算法,将每一个算法封装起来,并让它们可以相互替换。策略模式让算法独立于使用它的客户而变化。
使用策略模式重构后的程序结构:
定义一个AbstractFormula抽象类,在抽象类中定义一个Calculation计算方法,这个方法返回经过计算的结果的集合,在各个实现类(即具体公式)中实现Calculation方法
定义上下文类,在上下文类中指定要使用的公式,定义Caclute方法用于返回结果。
实现代码
/// <summary> /// 简易的方案信息 /// </summary> internal class Schemeinformation { //方案ID public string SchemeID { get; set; } //方案名称 public string SchemeName { get; set; } //公式 public string Formula { get; set; } } /// <summary> /// 单个结果 /// </summary> internal class Result { public Result(Schemeinformation schemeinformation, string Result) { Schemeinformation = schemeinformation; FinalResult=Result; } public string FinalResult { get; set; } public Schemeinformation Schemeinformation { get; set; } }
//抽象的公式类 internal abstract class AbstractFormula { //公式计算后的结果集 public List<string>? tempResultList; public abstract List<string> Caclution(Schemeinformation schemeinformation); }
//具体实现 internal class Formula1 : AbstractFormula { public override List<string> Caclution(Schemeinformation schemeinformation) { tempResultList = new List<string>(); //计算过程... 对tempResultList赋值 return tempResultList; } } internal class Formula2 : AbstractFormula { public override List<string> Caclution(Schemeinformation schemeinformation) { tempResultList = new List<string>(); //计算过程...其中需要使用到Schemeinformation中的信息 //对tempResultList赋值 return tempResultList; } }
/// <summary> /// 上下文类 使用公式,并管理结果集 /// </summary> internal class Context { AbstractFormula formula; public void SetFromula(AbstractFormula formula) { this.formula = formula; } public List<string> Caclute(Schemeinformation schemeinformation) { return formula.Caclution(schemeinformation); } }
/// <summary> /// 创建公式的简单工厂 /// </summary> internal class FormulaFactory { public static AbstractFormula GetFormula(string Formula) { if(Formula == "F1") { return new Formula1(); } else if(Formula == "F2") { return new Formula2(); } //以下若干..... else { //找不到这个公式,抛出异常 throw new ArgumentNullException("value", $"公式{Formula}不存在"); ; } } }
//实际使用 static void Main(string[] args) { Context context= new Context(); //获取所有方案信息 List<Schemeinformation> schemeinformationList = new List<Schemeinformation>(); //总结果集 List<Result> results= new List<Result>(); foreach(Schemeinformation schemeinformation in schemeinformationList) { //使用简单工厂获得公式对象 context.SetFromula(FormulaFactory.GetFormula(schemeinformation.Formula)); //获取当前公式的计算结果集 List<string>tempResults=context.Caclute(schemeinformation); //遍历结果,将所有结果放入到总结果集中 foreach(string tempResult in tempResults) { results.Add(new Result(schemeinformation,tempResult)); } } //下面就可以输出总结果集了 Console.WriteLine(results.Count); }