在不改變代碼外在行爲的前提下,對代碼作出修改以改進程序內部的結構
簡單地說就是在代碼寫好後改進它的設計程序員
帶着疑問去讀:數據結構
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 = (Rental)rentals.nextElement(); switch (each.getMovie().getPriceCode()) { case Movie.CHILDRENS: thisAmount += 1.5; if(each.getDaysRented()>3){ thisAmount += (each.getDaysRented()-3)*1.5; } break; case Movie.NEW_RELEASE: thisAmount += each.getDaysRented()*3; break; case Movie.REGULAR: thisAmount += 2; if(each.getDaysRented()>2){ thisAmount += (each.getDaysRented()-2)*1.5; } break; default: break; } frequentRenterPoints++; if(each.getMovie().getPriceCode()==Movie.NEW_RELEASE && each.getDaysRented()>1)frequentRenterPoints++; result += "\t"+each.getMovie().getTitle()+"\t"+String.valueOf(thisAmount)+"\n"; totalAmount +=thisAmount; } result += "Amount owed is " + String.valueOf(totalAmount) + "\n"; result += "You earned " + String.valueOf(frequentRenterPoints) + " frequent renter points "; return result; }
這是隻是一個方法。直接評價:太複雜,複用率低架構
將代碼按照功能拆分。每一個功能只作一件事。函數
private double amountFor(Rental each, double result) { switch (each.getMovie().getPriceCode()) { case Movie.CHILDRENS: result += 1.5; if(each.getDaysRented()>3){ result += (each.getDaysRented()-3)*1.5; } break; case Movie.NEW_RELEASE: result += each.getDaysRented()*3; break; case Movie.REGULAR: result += 2; if(each.getDaysRented()>2){ result += (each.getDaysRented()-2)*1.5; } break; default: break; } return result; }
變量名必須保證簡單清楚,不產生歧義。好比上方代碼的each就是可修改的變量名。由於each到底指的是什麼測試
由於這個方法只使用了rental的信息。因此須要放在rental類下this
statement方法中有兩個臨時變量totalAmount和frequentRenterPoints。 作成getTotalAmount和getFrequentRenterPoints方法設計
public String statement() { double totalAmount = 0; int frequentRenterPoints = 0; // Enumeration接口定義了從一個數據結構獲得連續數據的手段 Enumeration rentals = _rentals.elements(); String result = "Rental Record for" + getName() + "\n"; while (rentals.hasMoreElements()) { Rental each = (Rental) rentals.nextElement(); result += "\t" + each.getMovie().getTitle() + "\t" + String.valueOf(each.getMovie().getPrice().getCharge(each.getDayRented())) + "\n"; } result += "Amount owed is " + String.valueOf(getTotalCharge()) + "\n"; result += "You earned " + String.valueOf(getTotalFrequentRenterPoints()) + "frequent renter points"; return result; } private int getTotalFrequentRenterPoints(){ int result=0; Enumeration rentals=_rentals.elements(); while(rentals.hasMoreElements()){ Rental each=(Rental)rentals.nextElement(); result+=each.getMovie().getFrequentRenterPoints(each.getDayRented()); } return result; } private double getTotalCharge(){ double result =0; Enumeration rentals=_rentals.elements(); while(rentals.hasMoreElements()){ Rental each=(Rental)rentals.nextElement(); result+=each.getMovie().getPrice().getCharge(each.getDayRented()); } return result; }
保證重構後的方法可以知足全部的需求code