重构之前代码如下
影片类:
View Code
public class Moive { public Moive() { this.MoiveName = "十二生肖"; this.MoiveType = (int)MoivesType.New; } /// <summary> /// 影片名称 /// </summary> public string MoiveName { get; set; } /// <summary> /// 影片类型 /// </summary> public int MoiveType { get; set; } /// <summary> /// 返回影片类型 /// </summary> /// <returns></returns> public int GetMoiveType() { return this.MoiveType; } }
租赁类:
View Code
public class Rental { private Moive aMoive=new Moive(); public Moive GetMoive() { return aMoive; } /// <summary> /// 返回租片天数 /// </summary> /// <returns></returns> public int GetRentalDay() { return 5; } }
客户类:
View Code
public class Customer { public List<Rental> rentalList = new List<Rental>() { new Rental(),new Rental(),new Rental()}; public string Name { get; set; } /// <summary> /// 打印消费信息 /// </summary> /// <returns></returns> public string Print() { double totalMoney = 0; int freequen = 0; double currentMoney=0; Console.WriteLine("customer name is "+this.Name); //******************************** //其他业务逻辑 //******************************** foreach (var aRental in rentalList) { switch (aRental.GetMoive().GetMoiveType()) { case (int)MoivesType.Normal: { currentMoney = aRental.GetRentalDay() * 1.2; break; } case (int)MoivesType.New: { currentMoney = aRental.GetRentalDay() * 3.3; break; } case (int)MoivesType.Child: { currentMoney = aRental.GetRentalDay() * 0.3; break; } } Console.WriteLine("movie name is "+aRental.GetMoive().MoiveName+" and currentTotalMoney equals "+currentMoney); if ((int)MoivesType.New == aRental.GetMoive().MoiveType && aRental.GetRentalDay() > 1) { freequen++; } totalMoney+=currentMoney; } return "totalMoney equals " + totalMoney + " you earned " + freequen + " frequent"; } }
首先,让我们先看看客户类中Print()这个方法,该方法中存在switch语句,将其提出一个单独的方法:
View Code
private static double AmountFor(double currentMoney, Rental aRental) { switch (aRental.GetMoive().GetMoiveType()) { case (int)MoivesType.Normal: { currentMoney = aRental.GetRentalDay() * 1.2; break; } case (int)MoivesType.New: { currentMoney = aRental.GetRentalDay() * 3.3; break; } case (int)MoivesType.Child: { currentMoney = aRental.GetRentalDay() * 0.3; break; } } Console.WriteLine("movie name is " + aRental.GetMoive().MoiveName + " and currentTotalMoney equals " + currentMoney); return currentMoney; }
此时再将double currentMoney这个多余的参数给去掉:
View Code
private static double AmountFor(Rental aRental) { double currentMoney = 0; switch (aRental.GetMoive().GetMoiveType()) { case (int)MoivesType.Normal: { currentMoney = aRental.GetRentalDay() * 1.2; break; } case (int)MoivesType.New: { currentMoney = aRental.GetRentalDay() * 3.3; break; } case (int)MoivesType.Child: { currentMoney = aRental.GetRentalDay() * 0.3; break; } } Console.WriteLine("movie name is " + aRental.GetMoive().MoiveName + " and currentTotalMoney equals " + currentMoney); return currentMoney; }
再仔细观察后不难发现该方法中使用的对象属于租赁类,因此我们将该方法放置租赁类当中,将方法参数移除,并将方法体内aRental改为this当前对象的调用:
View Code
public class Rental { private Moive aMoive=new Moive(); public Moive GetMoive() { return aMoive; } /// <summary> /// 返回租片天数 /// </summary> /// <returns></returns> public int GetRentalDay() { return 5; } public double AmountFor() { double currentMoney = 0; switch (this.GetMoive().GetMoiveType()) { case (int)MoivesType.Normal: { currentMoney = this.GetRentalDay() * 1.2; break; } case (int)MoivesType.New: { currentMoney = this.GetRentalDay() * 3.3; break; } case (int)MoivesType.Child: { currentMoney = this.GetRentalDay() * 0.3; break; } } Console.WriteLine("movie name is " + this.GetMoive().MoiveName + " and currentTotalMoney equals " + currentMoney); return currentMoney; } }
客户类修改后代码如下:
View Code
public class Customer { public List<Rental> rentalList = new List<Rental>() { new Rental(),new Rental(),new Rental()}; public string Name { get; set; } /// <summary> /// 打印消费信息 /// </summary> /// <returns></returns> public string Print() { double totalMoney = 0; int freequen = 0; double currentMoney=0; Console.WriteLine("customer name is "+this.Name); //******************************** //其他业务逻辑 //******************************** foreach (var aRental in rentalList) { currentMoney = aRental.AmountFor(); if ((int)MoivesType.New == aRental.GetMoive().MoiveType && aRental.GetRentalDay() > 1) { freequen++; } totalMoney+=currentMoney; } return "totalMoney equals " + totalMoney + " you earned " + freequen + " frequent"; }
以同样的手法继续重构pinrt()方法,再次修改后的客户类如下:
View Code
public class Customer { public List<Rental> rentalList = new List<Rental>() { new Rental(),new Rental(),new Rental()}; public string Name { get; set; } /// <summary> /// 打印消费信息 /// </summary> /// <returns></returns> public string Print() { double totalMoney = 0; int freequen = 0; //double currentMoney=0; //去除临时变量 Console.WriteLine("customer name is " + this.Name); //******************************** //其他业务逻辑 //******************************** foreach (var aRental in rentalList) { freequen += aRental.GetFrenquent(); totalMoney += aRental.AmountFor(); ; } //return "totalMoney equals " + totalMoney + " you earned " + freequen + " frequent"; return "totalMoney equals " + totalMoney + " you earned " + freequen + " frequent"; }
租赁类如下:
View Code
public class Rental { private Moive aMoive=new Moive(); public Moive GetMoive() { return aMoive; } /// <summary> /// 返回租片天数 /// </summary> /// <returns></returns> public int GetRentalDay() { return 5; } public double AmountFor() { double currentMoney = 0; switch (this.GetMoive().GetMoiveType()) { case (int)MoivesType.Normal: { currentMoney = this.GetRentalDay() * 1.2; break; } case (int)MoivesType.New: { currentMoney = this.GetRentalDay() * 3.3; break; } case (int)MoivesType.Child: { currentMoney = this.GetRentalDay() * 0.3; break; } } Console.WriteLine("movie name is " + this.GetMoive().MoiveName + " and currentTotalMoney equals " + currentMoney); return currentMoney; } public int GetFrenquent() { int freequen = 0; if ((int)MoivesType.New == this.GetMoive().MoiveType && this.GetRentalDay() > 1) { freequen++; } return freequen; } }
在此重构过程中,主要是将实现某一功能的代码段分别提出为一个单独的方法,然后将不必要的方法参数给去掉,并将该方法放置其所对应的类中去,再修改之前引用的地方,改为引用重构之后的方法,同时,可以将一些不需要的临时变量给去除。
注意:
重构的步骤需要一步步执行,每次执行完之后需要编译、测试,确认此次重构没有问题了之后,然后再进行下一步的重构。
只有写出人类看的懂的代码,才是优秀的程序员。