《重构 改善既有代码的设计》读书笔记1
2012-01-08 09:29
162 查看
首先我们看重构之前的,共有三个类,Customer,Movie,Rental。全都是自己写的数据类。
我们可以看到,Customer中的statement()函数过于复杂,这时我们就开始想要重构了。
首先我们看到,很明显的就是statement()中的switch语句,我们应该把它放到单独的一个函数中,所以我们要对switch处进行重构。
第一次重构:提取函数后的Customer类
之后我们会发现amountFor()中的一些变量的名字不是很好,所以我们进行重命名
之后我们发现,amountFor()在Customer类中,可是却没有使用来自Customer类的信息,而是使用了来自Rental类的信息,所以我们需要考虑将amountFor()搬移到Rental类中
在这里我们同时改了一下函数名:amountFor() -> getCharge()
新的Rental:
新的Customer中的statement:
之后我们发现,stateme()中的thisAmount显得有点多余了,接受each.getCharge()的执行结果,然后就不会有任何修改,所以我们运用Replace Temp With Query把thisAmount去掉
新的statement():
下一步对“常客积分计算”做类似的处理,积分的计算视影片的种类而有所不同不过不像收费规则(getCharge())有那么多变化,我们将常客积分计算的任务交给Rental:
Rental中新增加的函数:
Customer的statement函数:
之后我们需要去除临时变量:
Customer中的statement函数以及新增加的getTotalCharge和getTotalFrequentRenterPoints函数
// Rental: 表示某个顾客租了一部影片 public class Rental { private Movie _movie; private int _daysRented; public Rental(Movie movie, int daysRented) { _movie = movie; _daysRented = daysRented; } public int getDaysRented() { return _daysRented; } public Movie getMovie() { return _movie; } }
// Movie: 纯数据类,代表一个影片 public class Movie { public static final int CHILDRENS = 2; public static final int REGULAR = 0; public static final int NEW_RELEASE = 1; private String _title; private int _priceCode; public Movie(String title, int priceCode) { _title = title; _priceCode = priceCode; } public int getPriceCode() { return _priceCode; } public void setPriceCode(int priceCode) { _priceCode = priceCode; } public String getTitle() { return _title; } }
// Customer: 顾客 public class Customer { private String _name; private Vector<Rental> _rentals = new Vector<Rental>(); public Customer(String name) { _name = name; } public void addRental(Rental rental) { _rentals.add(rental); } public String getName() { return _name; } public String statement() { double totalAmount = 0; int frequentRenterPoints = 0; Enumeration<Rental> rentals = _rentals.elements(); String result = "Rental record for " + getName() + "\n"; while(rentals.hasMoreElements()) { double thisAmount = 0; Rental each = rentals.nextElement(); // determine amounts for each line switch(each.getMovie().getPriceCode()) { case Movie.REGULAR: thisAmount += 2; if(each.getDaysRented() > 2) { thisAmount += (each.getDaysRented() - 2) * 1.5; } break; case Movie.NEW_RELEASE: thisAmount += each.getDaysRented() * 3; break; case Movie.CHILDRENS: thisAmount += 1.5; if(each.getDaysRented() > 3) { thisAmount += (each.getDaysRented() - 3) * 1.5; } break; } // add frequent renter points frequentRenterPoints++; // add bonus for a two day new release rental if((each.getMovie().getPriceCode() == Movie.NEW_RELEASE) && each.getDaysRented() > 1) { frequentRenterPoints++; } // show figures for this rental result += "\t" + each.getMovie().getTitle() + "\t" + thisAmount + "\n"; totalAmount += thisAmount; } // add footer lines result += "Amount owed is" + totalAmount + "\n"; result += "You earned " + frequentRenterPoints + "frequent renter points"; return result; } }
我们可以看到,Customer中的statement()函数过于复杂,这时我们就开始想要重构了。
首先我们看到,很明显的就是statement()中的switch语句,我们应该把它放到单独的一个函数中,所以我们要对switch处进行重构。
第一次重构:提取函数后的Customer类
// Customer: 顾客 public class Customer { private String _name; private Vector<Rental> _rentals = new Vector<Rental>(); public Customer(String name) { _name = name; } public void addRental(Rental rental) { _rentals.add(rental); } public String getName() { return _name; } public String statement() { double totalAmount = 0; int frequentRenterPoints = 0; Enumeration<Rental> rentals = _rentals.elements(); String result = "Rental record for " + getName() + "\n"; while(rentals.hasMoreElements()) { double thisAmount = 0; Rental each = rentals.nextElement(); thisAmount += amountFor(each); // add frequent renter points frequentRenterPoints++; // add bonus for a two day new release rental if((each.getMovie().getPriceCode() == Movie.NEW_RELEASE) && each.getDaysRented() > 1) { frequentRenterPoints++; } // show figures for this rental result += "\t" + each.getMovie().getTitle() + "\t" + thisAmount + "\n"; totalAmount += thisAmount; } // add footer lines result += "Amount owed is" + totalAmount + "\n"; result += "You earned " + frequentRenterPoints + "frequent renter points"; return result; } private double amountFor(Rental each) { double thisAmount = 0; // determine amounts for each line switch(each.getMovie().getPriceCode()) { case Movie.REGULAR: thisAmount += 2; if(each.getDaysRented() > 2) { thisAmount += (each.getDaysRented() - 2) * 1.5; } break; case Movie.NEW_RELEASE: thisAmount += each.getDaysRented() * 3; break; case Movie.CHILDRENS: thisAmount += 1.5; if(each.getDaysRented() > 3) { thisAmount += (each.getDaysRented() - 3) * 1.5; } break; } return thisAmount; } }
之后我们会发现amountFor()中的一些变量的名字不是很好,所以我们进行重命名
private double amountFor(Rental aRental) { double result = 0; // determine amounts for each line switch(aRental.getMovie().getPriceCode()) { case Movie.REGULAR: result += 2; if(aRental.getDaysRented() > 2) { result += (aRental.getDaysRented() - 2) * 1.5; } break; case Movie.NEW_RELEASE: result += aRental.getDaysRented() * 3; break; case Movie.CHILDRENS: result += 1.5; if(aRental.getDaysRented() > 3) { result += (aRental.getDaysRented() - 3) * 1.5; } break; } return result; }
之后我们发现,amountFor()在Customer类中,可是却没有使用来自Customer类的信息,而是使用了来自Rental类的信息,所以我们需要考虑将amountFor()搬移到Rental类中
在这里我们同时改了一下函数名:amountFor() -> getCharge()
新的Rental:
// Rental: 表示某个顾客租了一部影片 public class Rental { private Movie _movie; private int _daysRented; public Rental(Movie movie, int daysRented) { _movie = movie; _daysRented = daysRented; } public int getDaysRented() { return _daysRented; } public Movie getMovie() { return _movie; } public double getCharge() { double result = 0; // determine amounts for each line switch(getMovie().getPriceCode()) { case Movie.REGULAR: result += 2; if(getDaysRented() > 2) { result += (getDaysRented() - 2) * 1.5; } break; case Movie.NEW_RELEASE: result += getDaysRented() * 3; break; case Movie.CHILDRENS: result += 1.5; if(getDaysRented() > 3) { result += (getDaysRented() - 3) * 1.5; } break; } return result; } }
新的Customer中的statement:
public String statement() { double totalAmount = 0; int frequentRenterPoints = 0; Enumeration<Rental> rentals = _rentals.elements(); String result = "Rental record for " + getName() + "\n"; while(rentals.hasMoreElements()) { double thisAmount = 0; Rental each = rentals.nextElement(); thisAmount += each.getCharge(); // add frequent renter points frequentRenterPoints++; // add bonus for a two day new release rental if((each.getMovie().getPriceCode() == Movie.NEW_RELEASE) && each.getDaysRented() > 1) { frequentRenterPoints++; } // show figures for this rental result += "\t" + each.getMovie().getTitle() + "\t" + thisAmount + "\n"; totalAmount += thisAmount; } // add footer lines result += "Amount owed is" + totalAmount + "\n"; result += "You earned " + frequentRenterPoints + "frequent renter points"; return result; }
之后我们发现,stateme()中的thisAmount显得有点多余了,接受each.getCharge()的执行结果,然后就不会有任何修改,所以我们运用Replace Temp With Query把thisAmount去掉
新的statement():
public String statement() { double totalAmount = 0; int frequentRenterPoints = 0; Enumeration<Rental> rentals = _rentals.elements(); String result = "Rental record for " + getName() + "\n"; while(rentals.hasMoreElements()) { Rental each = rentals.nextElement(); // add frequent renter points frequentRenterPoints++; // add bonus for a two day new release rental if((each.getMovie().getPriceCode() == Movie.NEW_RELEASE) && each.getDaysRented() > 1) { frequentRenterPoints++; } // show figures for this rental result += "\t" + each.getMovie().getTitle() + "\t" + each.getCharge() + "\n"; totalAmount += each.getCharge(); } // add footer lines result += "Amount owed is" + totalAmount + "\n"; result += "You earned " + frequentRenterPoints + "frequent renter points"; return result; }
下一步对“常客积分计算”做类似的处理,积分的计算视影片的种类而有所不同不过不像收费规则(getCharge())有那么多变化,我们将常客积分计算的任务交给Rental:
Rental中新增加的函数:
public int getFrequentRentalPoints() { int frequentRenterPoints = 0; frequentRenterPoints++; if(getMovie().getPriceCode() == Movie.NEW_RELEASE && getDaysRented() > 1) { frequentRenterPoints++; } return frequentRenterPoints; }
Customer的statement函数:
public String statement() { double totalAmount = 0; int frequentRenterPoints = 0; Enumeration<Rental> rentals = _rentals.elements(); String result = "Rental record for " + getName() + "\n"; while(rentals.hasMoreElements()) { Rental each = rentals.nextElement(); frequentRenterPoints += each.getFrequentRentalPoints(); // show figures for this rental result += "\t" + each.getMovie().getTitle() + "\t" + each.getCharge() + "\n"; totalAmount += each.getCharge(); } // add footer lines result += "Amount owed is" + totalAmount + "\n"; result += "You earned " + frequentRenterPoints + "frequent renter points"; return result; }
之后我们需要去除临时变量:
Customer中的statement函数以及新增加的getTotalCharge和getTotalFrequentRenterPoints函数
public String statement() { Enumeration<Rental> rentals = _rentals.elements(); String result = "Rental record for " + getName() + "\n"; while(rentals.hasMoreElements()) { Rental each = rentals.nextElement(); // show figures for this rental result += "\t" + each.getMovie().getTitle() + "\t" + each.getCharge() + "\n"; } // add footer lines result += "Amount owed is" + getTotalCharge() + "\n"; result += "You earned " + getTotalFrequentRenterPoints() + "frequent renter points"; return result; } private int getTotalFrequentRenterPoints() { int result = 0; for(int n=0; n<_rentals.size(); n++) { result += _rentals.get(n).getFrequentRentalPoints(); } return result; } private double getTotalCharge() { double result = 0; for(int n=0; n<_rentals.size(); n++) { result += _rentals.get(n).getCharge(); } return result; }
相关文章推荐
- 《重构-改善既有代码的设计》读书笔记
- 《重构-改善既有代码的设计》读书笔记(二)
- 《重构_改善既有代码的设计》读书笔记
- 重构 改善既有代码的设计(读书笔记1)
- 《重构-改善既有代码的设计》读书笔记
- 《重构-改善既有代码的设计》读书笔记
- 《重构--改善既有代码的设计》读书笔记之四:将条件分支语句放入合适类中
- 重构指南 - 使用多态代替条件判断(Replace conditional with Polymorphism)
- Eclipse重构——Move Method(III)
- spring 项目 重构后无法扫描文件
- 学习之路二十九:泛型和委托在重构中的运用
- 重构了cxlt-vue2-toastr插件
- 重构机房收费系统——起步
- 【机房重构】--职责链模式+策略模式 实现下机
- 漫谈重构(转载)
- 机房重构——父窗体、子窗体的显示
- Activity初级:resultCode返回码、 onclick代码重构
- 重构笔记——代码的坏味道(上)
- 【前端重构技能天赋】(一)——内容篇
- Java项目重构Maven之pom使用总结