- A+
六、重构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的菜单栏上找到“测试-->运行所有测试”菜单项。或者在“测试资源管理器中”选择 “在视图中运行所有测试”按钮, 运行测试用例。监测重构的结果是否正确。如下图。