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