八. 重構5:繼續將相應的方法進行移動(Move Method)
通過“程式碼重構與單元測試——“提取方法”重構(三) ”至“程式碼重構與單元測試——使用“以查詢取代臨時變數”再次對Statement()方法進行重構(七) ”這幾篇文章的幾次重構之後,再次對充電寶計費專案的程式碼進行全域性性的觀察與分析,我們發現在Rental類中的GetAmount()與GetFrequentRenterPoints()方法中的程式碼對PowerBank類有較大的依賴。因為這兩個方法都只用到了Rental類中的RentedTime屬性,而多次用到了PowerBank中的屬性或欄位。通過上面的分析,我們認為將這兩個方法中的程式碼移到PowerBank類中顯得更為合理。接下來,我們繼續進行這兩個方法的重構——將該部分程式碼移動到PowerBank類中。
1. 這次跟之前的“程式碼重構與單元測試——將方法移到合適[依賴]的類中(六) ”文章中的移動方法不同,這次要在Rental中保留這兩個方法的宣告,在PowerBank類中建立新的同方法名稱的方法,將方法的內容移到PowerBank中後,在Rental中呼叫PowerBank類中的方法。下面是我們經過這次重構後我們PowerBank類中的內容。其中紅色的程式碼是我們移過來的程式碼,而斜體的程式碼,是引數需要從外界傳入。具體程式碼如下:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace LeasePowerBank { /// <summary> /// 充電寶類 /// </summary> public class PowerBank { //地段人流量種類 public static int LowTraffic = 0;//低人流量地段 public static int MiddleTraffic = 1;//中人流量地段 public static int HighTraffic = 2; //高人流量地段 public int PriceCode; //價格程式碼 public string Title;//充電寶名稱 public PowerBank(string title,int priceCode) { PriceCode = priceCode; Title = title; } /// <summary> /// 根據消費金額,充電寶所處地段,進行積分計算 /// </summary> /// <param name="RentedTime">租賃時間</param> /// <returns></returns> public int GetFrequentRenterPoints(int RentedTime) { int frequentRenterPoints = 0; decimal amount = GetAmount(RentedTime); //計算積分 if (this.PriceCode == HighTraffic && RentedTime > 4) { frequentRenterPoints += (int)Math.Ceiling(amount * 1.5M); } else frequentRenterPoints += (int)Math.Ceiling(amount); return frequentRenterPoints; } /// <summary> /// 根據充電寶訂單,計算總金額 /// </summary> /// <param name="RentedTime">租賃時間</param> /// <returns></returns> public decimal GetAmount(int RentedTime) { decimal amount = 0M; switch (this.PriceCode) { case 0: amount = RentedTime; if (RentedTime > 12) { amount = 12; } break; case 1: amount = RentedTime * 3; if (RentedTime > 24) { amount = 24; } break; case 2: amount = RentedTime * 5; if (RentedTime > 50) { amount = 50; } break; default: break; } return amount; } } }
2.將相應的方法程式碼移動PowerBank類中後,在Rental中我們需要對其進行呼叫。在呼叫相應的方法時傳入相應的引數即可。如下圖,圖中程式碼就是經過這次重構之後的Rental類的程式碼,紅框中的程式碼就是對PowerBank中新新增的方法的呼叫。程式碼如下所示:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace LeasePowerBank { /// <summary> /// 租賃類 /// </summary> public class Rental { public PowerBank Power ; //充電寶名稱 public int RentedTime;//租賃時間 public Rental(PowerBank powerbk,int rentedTime) { Power = powerbk; RentedTime = rentedTime; } /// <summary> /// 根據消費金額,充電寶所處地段,進行積分計算 /// </summary> /// <returns></returns> public int GetFrequentRenterPoints() { return this.Power.GetFrequentRenterPoints(RentedTime); } /// <summary> /// 根據充電寶訂單,計算總金額 /// </summary> /// <returns></returns> public decimal GetAmount() { return this.Power.GetAmount(RentedTime); } } }
3. 我們的測試用例依然不變。在每次重構後我們都需要呼叫上述的測試用例來檢查重構是否產生了副作用。現在我們的類間的依賴關係沒怎麼發生變化,只是相應類中的方法有些變化。在Visual Studio 2019的選單欄上找到“測試-->執行所有測試”選單項。或者在“測試資源管理器中”選擇 “在檢視中執行所有測試”按鈕, 執行測試用例。監測重構的結果是否正確。如下圖。