6、 Reconstruction3: move the method to the appropriate [dependent] class
After previous refactoring (see article)Code refactoring and unit testing — refactoring of “extraction method” (3)AndCode refactoring and unit testing — refactoring method parameters (5)), we extracted two methods from the statement () method. Looking at the two reconstructed methods, it is not difficult to see that the two encapsulated new methods only need one parameter, which is the object of the rental class. That is, both methods depend on the rental class, but not on the current class where the method is located. The reason for this is that these two methods are misplaced, because they are placed in the customer class, but do not depend on the customer class and depend on the rental class, which is enough to explain that these two methods should be placed in the rental class.
1. After simple analysis, we can decide to put the newly extracted method into the rental class and remove the parameters of the method. Because the method is in the rental class, you can use this directly in the method. Move the method of calculating the amount and the method of calculating the integral to the rental class.
2. Open rental in the visual studio 2019 code editor CS file, the getamount and getfrequentrenterpoints methods from customer CS file to rental CS file. The specific code is as follows:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace LeasePowerBank
{
///
///Leasing
///
public class Rental
{
public PowerBank Power ; // Name of power bank
public int RentedTime;// Lease time
public Rental(PowerBank powerbk,int rentedTime)
{
Power = powerbk;
RentedTime = rentedTime;
}
public int GetFrequentRenterPoints()
{
int frequentRenterPoints = 0;
decimal amount = GetAmount();
//Calculate integral
if (this.Power.PriceCode == PowerBank.HighTraffic && this.RentedTime > 4)
{
frequentRenterPoints += (int)Math.Ceiling(amount * 1.5M);
}
else
frequentRenterPoints += (int)Math.Ceiling(amount);
return frequentRenterPoints;
}
///
///Calculate the total amount according to the order of power bank
///
///
///
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
{
///
///Customer class
///
public class Customer
{
string Name;// User name
public List listRentals=new List();// User leased power bank
public Customer(string name)
{
Name = name;
}
public void AddRental(Rental rental)
{
listRentals.Add(rental);
}
public string Statement()
{
decimal totalAmount = 0M; // Total amount
int frequentRenterPoints = 0; // User points
String result = $"{name}" lease Bill: \ n ";
foreach (var item in listRentals)
{
decimal amount = item. GetAmount();// Total price calculation
totalAmount += amount;
frequentRenterPoints = item.GetFrequentRenterPoints();
}
Result + = $"total amount: {totalamount} \ n";
Result + = $"you have obtained: {frequentrenterpoints} points this time";
return result;
}
}
}
4. Open unittest1 in the test project leasepowerbanktest in Visual Studio 2019 CS test class file, we also need to modify the test cases in unit testing. Modify the method in the customer class to call the method in the rental class. The code is as follows:
[TestMethod]
public void ValidGetAmountTest()
{
double expected = 5;
//Create user
Var customer = new customer ("Zhang San");
//Create a power bank
Powerbank regularpowerbank = new powerbank ("low - power bank", powerbank. Lowtraffic);
//Create lease data
var rental1 = new Rental(regularPowerBank, 5);
// Act
double actual = (double)rental1.GetAmount();
// Assert
Assert. Areequal (expected, actual, 0.001, $"total amount calculation error, actual calculation amount {actual}, expected amount: {expected}");
}
[TestMethod]
public void ValidGetFrequentRenterPointsTest()
{
int expected = 5;
//Create user
Var customer = new customer ("Zhang San");
//Create a power bank
Powerbank regularpowerbank = new powerbank ("low - power bank", powerbank. Lowtraffic);
//Create lease data
var rental1 = new Rental(regularPowerBank, 5);
// Act
int actual = rental1.GetFrequentRenterPoints();
// Assert
Assert. Areequal (expected, actual, 0.001, "integral calculation error");
}
5. Find the menu item “test — > run all tests” on the menu bar of visual studio 2019. Or select “run all tests in view” button in “test Explorer” to run test cases. Monitor whether the reconstruction results are correct. As shown below.