業務流程:
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); }