程式碼重構與單元測試——使用「以查詢取代臨時變數」再次對Statement()方法進行重構(七)
七、重構4:使用「以查詢取代臨時變數」再次對Statement()方法進行重構
1. 經過了之前幾篇文章的重構後,Customer中的statement()方法的具體程式碼,如下圖所示。在計算每部電影的金額和積分時,我們調用的是Rental類的對象的相應的方法。下圖中的方法與充電項計費項目的原始程式碼中的方法相比可謂是簡潔了許多,而且易於理解與維護。
2.不過上面的程式碼仍然有重構的空間,舉個例子,如果我們要將結果以HTML的形式進行組織的話,我們需要將上面的程式碼進行複製,然後修改result變數的文本組織方式即可。這可能就是程式設計師經常做的事情Ctrl+C、Ctrl+V,很多程式設計師是這樣來修改程式碼的,這種修改程式碼快速,功能實現方便,但是這樣的修改程式碼會給我們的系統遺留很多無用的程式碼。使用Ctrl+C、Ctrl+V這種非常方便的方式來修改程式碼,會造成方法中的好多臨時變數都被複制一份,這是完全相同的,這樣就容易產生重複的程式碼。在這種情況下,我們需要使用「Replace Temp with Query」(已查詢取代臨時變數)的重構手法來取出上圖所示的紅框中的臨時變數。
上圖中紅框所框出來的每個臨時變數我們都會提取出一個查詢方法,下圖中所示的程式碼,就是使用「Replace Temp with Query」(已查詢取代臨時變數)規則重構後的Statement()方法,以及提取的兩個查詢函數。
3.經過上面這些步驟的重構,Customer類的具體程式碼如下所示:
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()
{
string result = $"{Name} 的租賃賬單:\n";
result += $"總金額為:{GetTotalAmount()}\n";
result += $"你本次獲得了:{GetTotalFrequentRenterPoints()}積分 ";
return result;
}
/// <summary>
/// 計算總金額
/// </summary>
private decimal GetTotalAmount()
{
decimal totalAmount = 0M; //總金額
foreach (var item in listRentals)
{
totalAmount+= item.GetAmount();//總價計算
}
return totalAmount;
}
/// <summary>
/// 計算積分
/// </summary>
private decimal GetTotalFrequentRenterPoints()
{
int frequentRenterPoints = 0; //用戶積分
foreach (var item in listRentals)
{
frequentRenterPoints += item.GetFrequentRenterPoints();//計算積分
}
return frequentRenterPoints;
}
}
}