八. 重構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的菜單欄上找到“測試-->運行所有測試”菜單項。或者在“測試資源管理器中”選擇 “在視圖中運行所有測試”按鈕, 運行測試用例。監測重構的結果是否正確。如下圖。