Я собираюсь начать эту книгу с примера рифэкторинга. Я покажу как проводится рифэкторинг и дам вам почувствовать процесс. После этого я смогу сделать традиционное введениие в принципы.
Однако, с вводным примером возникает определенная проблема. Если выбрать большую программу, то читателю будет сложно понять, как был проведен рифэкторинг (я попробовал, и даже не очень сложный пример занял более чем сотню страниц). В то же время, если программа будет достаточно маленькой для понимания, то рифэкторинг не будет выглядеть заслуживающим внимания.
Таким образом я в классическом тупике, как и любой другой, кто хочет описать технику, применимую для реальных приложений. Откровенно говоря, нет большого смысла делать рифэкторинг той небольшой программы, который я собираюсь вам показать. Но если этот код является частью большой системы, то рифэкторинг сразу становится важным. Поэтому я прошу посмотреть и представить это в контексте большой системы.
Модель системы представлена несколькими классами (см. Рис 1.1)
Ниже вы можете увидеть код каждого из этих классов.
Рис 1.1 Диаграмма классов исходной программы в UML нотации
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) { this.title = title; this.priceCode = priceCode; } public int getPriceCode() { return priceCode; } public void setPriceCode( int priceCode) { this.priceCode = priceCode; } public String getTitle() { return title; } }
Класс Rental представляет данные о прокате фильма.
public class Rental { private Movie movie; private int daysRented; public Rental( Movie movie, int daysRented) { this.movie = movie; this.daysRented = daysRented; } public int getDaysRented() { return daysRented; } public void setDaysRented( int daysRented) { this.daysRented = daysRented; } public Movie getMovie() { return movie; } }
public class Customer { private String name; private Vector rentals = new Vector(); public Customer( String name) { this.name = name; } public void addRental( Rental rental) { rentals.addElement( rental); } public String getName() { return name; }Помимо этого, Customer имеет метод, который создает отчет:
public String statement() { double totalAmount = 0; int frequentRenterPoints = 0; Enumeration rentals = this.rentals.elements(); String result = "Rental Record for "+getName()+"\n"; while( rentals.hasMoreElements()) { double thisAmount = 0; Rental each = ( Rental) rentals.nextElement(); // determine amounts for each line switch() { 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"+ String.valueOf( thisAmount)+"\n"; totalAmount += thisAmount; } // add footer lines result += "Amount owned is "+String.valueOf( totalAmount)+"\n"; result += "You earned "+String.valueOf( frequentRenterPoints)+ " frequent renter points"; return result; } }Sequence диаграмма для этого метода показана на Рис. 1.2
Рис 1.2 Sequence диаграмма для метода statement
В начало | следующая