重構,第一個案例,重構前的程式碼
阿新 • • 發佈:2018-11-05
《重構:改善既有程式碼的設計》第一章 重構,第一個案例
此程式碼用於練習重構手法,侵刪!
影片類:
public class Movie { public final static int REGULAR = 0; public final static int NEW_RELEASE = 1; public final static int CHILDRENS = 2; private String title; private int priceCode; public Movie(String title, int priceCode) { super(); this.title = title; this.priceCode = priceCode; } public int getPriceCode() { return priceCode; } public void setPriceCode(int priceCode) { this.priceCode = priceCode; } public String getTitle() { return title; } }
租賃類:
public class Rental { private Movie movie; private int daysRented; public Rental(Movie movie, int daysRented) { super(); this.movie = movie; this.daysRented = daysRented; } public Movie getMovie() { return movie; } public int getDaysRented() { return daysRented; } }
顧客類:
import java.util.Enumeration; import java.util.Vector; public class Customer { private String name; private Vector<Rental> rentals = new Vector<>(); public Customer(String name) { super(); this.name = name; } public String getName() { return name; } public void addRental(Rental rental) { rentals.add(rental); } public String statement() {// 生成詳單 double totalAmount = 0; int frequentRenterPoints = 0; Enumeration<Rental> rentals = this.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; } }
首先,建立一組可靠的測試環境:
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
public class CustomerTest {
private Customer customer;
@BeforeEach
void init() {
customer = new Customer("小明");
customer.addRental(new Rental(new Movie("喜劇之王", Movie.REGULAR), 3));
customer.addRental(new Rental(new Movie("國產零零柒", Movie.REGULAR), 5));
customer.addRental(new Rental(new Movie("西虹市首富", Movie.NEW_RELEASE), 1));
customer.addRental(new Rental(new Movie("貓和老鼠", Movie.CHILDRENS), 6));
}
@Test
void testStatement() {
String statement = customer.statement();
String expected = "Rental record for 小明\n" +
"\t喜劇之王\t3.5\n" +
"\t國產零零柒\t6.5\n" +
"\t西虹市首富\t3.0\n" +
"\t貓和老鼠\t6.0\n" +
"Amount owed is 19.0\n" +
"You earned 4frequent renter points";
assertEquals(expected , statement);
}
@Test
void testHtmlStatement() {
String htmlStatement = customer.htmlStatement();
String expected = "<H1>Rentals for <EM>小明</EM></H1><P>\n" +
"喜劇之王: 3.5<BR/>\n" +
"國產零零柒: 6.5<BR/>\n" +
"西虹市首富: 3.0<BR/>\n" +
"貓和老鼠: 6.0<BR/>\n" +
"<P>You owe <EM>19.0</EM></P>\n" +
"On this rental you earned <EM>4</EM> frequent renter points</P>";
assertEquals(expected , htmlStatement);
}
}
重構操作(略):
分解並重組 statement();
運用多型取代與價格相關的條件邏輯;