六、重構3:將方法移到合適[依賴]的類中
經過之前的重構(見文章 代碼重構與單元測試——“提取方法”重構(三) 與代碼重構與單元測試——對方法的參數進行重構(五) ),我們從Statement()方法中提取了兩個方法。觀察這兩個重構后的方法我們不難看出,這兩個封裝出來的新方法都只需要一個參數,這個參數就是Rental類的對象。也就是這兩個方法都依賴於Rental類,而對該方法所在的當前類不太依賴。之所以會這種情況,是因為這兩個方法放錯了地方,因為這兩個方法放在Customer類中但不依賴與Customer類而依賴於Rental類,那就足以說明這兩個方法應該放在Rental類中。
1.經過簡單的分析后,我們就可以決定要將新提取的方法放到Rental類中,並且方法的參數去掉。因為方法在Rental類中,所以在方法中直接使用this即可。將計算金額的方法和計算積分的方法移到Rental類中。
2. 在Visual Studio 2019代碼編輯器中打開Rental.cs文件,將GetAmount和GetFrequentRenterPoints方法從Customer.cs文件中移到Rental.cs文件中。具體代碼如下所示:
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; } public int GetFrequentRenterPoints() { int frequentRenterPoints = 0; decimal amount = GetAmount(); //計算積分
if (this.Power.PriceCode == PowerBank.HighTraffic && this.RentedTime > 4) { frequentRenterPoints += (int)Math.Ceiling(amount * 1.5M); } else frequentRenterPoints += (int)Math.Ceiling(amount); return frequentRenterPoints; } /// <summary>
/// 根據充電寶訂單,計算總金額 /// </summary>
/// <param name="item"></param>
/// <returns></returns>
public decimal GetAmount() { decimal amount = 0M; switch (this.Power.PriceCode) { case 0: amount = this.RentedTime; if (this.RentedTime > 12) { amount = 12; } break; case 1: amount = this.RentedTime * 3; if (this.RentedTime > 24) { amount = 24; } break; case 2: amount = this.RentedTime * 5; if (this.RentedTime > 50) { amount = 50; } break; default: break; } return amount; } } }
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace LeasePowerBank { /// <summary>
/// 客戶類 /// </summary>
public class Customer { string Name;//用戶名稱
public List<Rental> listRentals=new List<Rental>();//用戶租賃的充電寶
public Customer(string name) { Name = name; } public void AddRental(Rental rental) { listRentals.Add(rental); } public string Statement() { decimal totalAmount = 0M; //總金額
int frequentRenterPoints = 0; //用戶積分
string result = $"{Name} 的租賃賬單:\n"; foreach (var item in listRentals) { decimal amount = item.GetAmount();//總價計算
totalAmount += amount; frequentRenterPoints = item.GetFrequentRenterPoints(); } result += $"總金額為:{totalAmount}\n"; result += $"你本次獲得了:{frequentRenterPoints}積分 "; return result; } } }
4. 在Visual Studio 2019中打開測試項目LeasePowerBankTest中的UnitTest1.cs測試類文件,對單元測試中的測試用例我們也要進行一下修改。將調用Customer類中的方法,修改為調用Rental類中的方法。代碼如下:
[TestMethod] public void ValidGetAmountTest() { double expected = 5; //創建用戶
var customer = new Customer("張三"); //創建充電寶
PowerBank regularPowerBank = new PowerBank("低-充電寶", PowerBank.LowTraffic); //創建租賃數據
var rental1 = new Rental(regularPowerBank, 5); // Act
double actual = (double)rental1.GetAmount(); // Assert
Assert.AreEqual(expected,actual,0.001, $"總金額計算錯誤,實際計算金額{actual},期望金額:{expected}"); } [TestMethod] public void ValidGetFrequentRenterPointsTest() { int expected = 5; //創建用戶
var customer = new Customer("張三"); //創建充電寶
PowerBank regularPowerBank = new PowerBank("低-充電寶", PowerBank.LowTraffic); //創建租賃數據
var rental1 = new Rental(regularPowerBank, 5); // Act
int actual = rental1.GetFrequentRenterPoints(); // Assert
Assert.AreEqual(expected, actual, 0.001, "積分計算錯誤"); }
5. 在Visual Studio 2019的菜單欄上找到“測試-->運行所有測試”菜單項。或者在“測試資源管理器中”選擇 “在視圖中運行所有測試”按鈕, 運行測試用例。監測重構的結果是否正確。如下圖。