commit
d6e078bf3d
@ -0,0 +1,34 @@ |
||||
Movie Rental |
||||
=========== |
||||
|
||||
This source code follows Martin Fowler's book " Refactoring, Improving the Design of Existing Code". |
||||
|
||||
When you find you have to add a feature to a program, and the program's code is not |
||||
structured in a convenient way to add the feature, first refactor the program to make it |
||||
easy to add the feature, then add the feature. |
||||
|
||||
Whenever you do refactoring, the first step is always the same. |
||||
You need to build a solid set of tests for that section of code. The tests are essential because even |
||||
though you follow refactorings structured to avoid most of the opportunities for introducing bugs, |
||||
you are still human and still make mistakes. Thus you need solid tests. |
||||
|
||||
Usage |
||||
----- |
||||
|
||||
The purpose of this is to provide good examples for the refactoring workshop. |
||||
|
||||
Build |
||||
----- |
||||
|
||||
All you need to build this project is Java 6.0 (Java SDK 1.6) or later, Maven 3.0 or later. |
||||
|
||||
Testing |
||||
------- |
||||
|
||||
Unit tests can be run using maven[1]: |
||||
|
||||
$ mvn test |
||||
|
||||
[1]: http://maven.apache.org/ |
||||
|
||||
Tests are located in the test directory and run using Junit. |
||||
@ -0,0 +1,20 @@ |
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" |
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
||||
<modelVersion>4.0.0</modelVersion> |
||||
|
||||
<groupId>com.refactoring</groupId> |
||||
<artifactId>movie-rental</artifactId> |
||||
<version>0.1</version> |
||||
|
||||
<dependencies> |
||||
<dependency> |
||||
<groupId>junit</groupId> |
||||
<artifactId>junit</artifactId> |
||||
<version>4.11</version> |
||||
<scope>test</scope> |
||||
</dependency> |
||||
</dependencies> |
||||
|
||||
</project> |
||||
@ -0,0 +1,64 @@ |
||||
package movierental; |
||||
import java.util.ArrayList; |
||||
import java.util.List; |
||||
|
||||
public class Customer { |
||||
|
||||
private String _name; |
||||
private List<Rental> _rentals = new ArrayList<Rental>(); |
||||
|
||||
public Customer(String name) { |
||||
_name = name; |
||||
} |
||||
|
||||
public void addRental(Rental arg) { |
||||
_rentals.add(arg); |
||||
} |
||||
|
||||
public String getName() { |
||||
return _name; |
||||
} |
||||
|
||||
public String statement() { |
||||
double totalAmount = 0; |
||||
int frequentRenterPoints = 0; |
||||
String result = "Rental Record for " + getName() + "\n"; |
||||
|
||||
for (Rental each: _rentals) { |
||||
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; |
||||
} |
||||
|
||||
// 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 owed is " + String.valueOf(totalAmount) + "\n"; |
||||
result += "You earned " + String.valueOf(frequentRenterPoints) + " frequent renter points"; |
||||
|
||||
return result; |
||||
} |
||||
} |
||||
@ -0,0 +1,29 @@ |
||||
package movierental; |
||||
|
||||
public class Movie { |
||||
|
||||
public static final int CHILDRENS = 2; |
||||
public static final int NEW_RELEASE = 1; |
||||
public static final int REGULAR = 0; |
||||
|
||||
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 arg) { |
||||
_priceCode = arg; |
||||
} |
||||
public String getTitle() { |
||||
return _title; |
||||
} |
||||
|
||||
|
||||
} |
||||
@ -0,0 +1,23 @@ |
||||
package movierental; |
||||
|
||||
/** |
||||
* The rental class represents a customer renting a movie. |
||||
*/ |
||||
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; |
||||
} |
||||
} |
||||
@ -0,0 +1,30 @@ |
||||
package movierental; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.Collections; |
||||
import java.util.List; |
||||
|
||||
public class CustomerBuilder { |
||||
|
||||
public static final String NAME = "Gregroire"; |
||||
private String name = NAME; |
||||
private List<Rental> rentals = new ArrayList<Rental>(); |
||||
|
||||
public Customer build() { |
||||
Customer result = new Customer(name); |
||||
for (Rental rental : rentals) { |
||||
result.addRental(rental); |
||||
} |
||||
return result; |
||||
} |
||||
|
||||
public CustomerBuilder withName(String name) { |
||||
this.name = name; |
||||
return this; |
||||
} |
||||
|
||||
public CustomerBuilder withRentals(Rental... rentals) { |
||||
Collections.addAll(this.rentals, rentals); |
||||
return this; |
||||
} |
||||
} |
||||
@ -0,0 +1,104 @@ |
||||
package movierental; |
||||
import static junit.framework.Assert.assertEquals; |
||||
import static junit.framework.Assert.assertNotNull; |
||||
|
||||
import org.junit.Test; |
||||
|
||||
public class CustomerTest { |
||||
|
||||
@Test |
||||
public void testCustomer() { |
||||
Customer c = new CustomerBuilder().build(); |
||||
assertNotNull(c); |
||||
} |
||||
|
||||
@Test |
||||
public void testAddRental() { |
||||
Customer customer2 = new CustomerBuilder().withName("Sallie").build(); |
||||
Movie movie1 = new Movie("Gone with the Wind", Movie.REGULAR); |
||||
Rental rental1 = new Rental(movie1, 3); // 3 day rental
|
||||
customer2.addRental(rental1); |
||||
} |
||||
|
||||
@Test |
||||
public void testGetName() { |
||||
Customer c = new Customer("David"); |
||||
assertEquals("David", c.getName()); |
||||
} |
||||
|
||||
@Test |
||||
public void statementForRegularMovie() { |
||||
Movie movie1 = new Movie("Gone with the Wind", Movie.REGULAR); |
||||
Rental rental1 = new Rental(movie1, 3); // 3 day rental
|
||||
Customer customer2 = |
||||
new CustomerBuilder() |
||||
.withName("Sallie") |
||||
.withRentals(rental1) |
||||
.build(); |
||||
String expected = "Rental Record for Sallie\n" + |
||||
"\tGone with the Wind\t3.5\n" + |
||||
"Amount owed is 3.5\n" + |
||||
"You earned 1 frequent renter points"; |
||||
String statement = customer2.statement(); |
||||
assertEquals(expected, statement); |
||||
} |
||||
|
||||
@Test |
||||
public void statementForNewReleaseMovie() { |
||||
Movie movie1 = new Movie("Star Wars", Movie.NEW_RELEASE); |
||||
Rental rental1 = new Rental(movie1, 3); // 3 day rental
|
||||
Customer customer2 = |
||||
new CustomerBuilder() |
||||
.withName("Sallie") |
||||
.withRentals(rental1) |
||||
.build(); |
||||
String expected = "Rental Record for Sallie\n" + |
||||
"\tStar Wars\t9.0\n" + |
||||
"Amount owed is 9.0\n" + |
||||
"You earned 2 frequent renter points"; |
||||
String statement = customer2.statement(); |
||||
assertEquals(expected, statement); |
||||
} |
||||
|
||||
@Test |
||||
public void statementForChildrensMovie() { |
||||
Movie movie1 = new Movie("Madagascar", Movie.CHILDRENS); |
||||
Rental rental1 = new Rental(movie1, 3); // 3 day rental
|
||||
Customer customer2 |
||||
= new CustomerBuilder() |
||||
.withName("Sallie") |
||||
.withRentals(rental1) |
||||
.build(); |
||||
String expected = "Rental Record for Sallie\n" + |
||||
"\tMadagascar\t1.5\n" + |
||||
"Amount owed is 1.5\n" + |
||||
"You earned 1 frequent renter points"; |
||||
String statement = customer2.statement(); |
||||
assertEquals(expected, statement); |
||||
} |
||||
|
||||
@Test |
||||
public void statementForManyMovies() { |
||||
Movie movie1 = new Movie("Madagascar", Movie.CHILDRENS); |
||||
Rental rental1 = new Rental(movie1, 6); // 6 day rental
|
||||
Movie movie2 = new Movie("Star Wars", Movie.NEW_RELEASE); |
||||
Rental rental2 = new Rental(movie2, 2); // 2 day rental
|
||||
Movie movie3 = new Movie("Gone with the Wind", Movie.REGULAR); |
||||
Rental rental3 = new Rental(movie3, 8); // 8 day rental
|
||||
Customer customer1 |
||||
= new CustomerBuilder() |
||||
.withName("David") |
||||
.withRentals(rental1, rental2, rental3) |
||||
.build(); |
||||
String expected = "Rental Record for David\n" + |
||||
"\tMadagascar\t6.0\n" + |
||||
"\tStar Wars\t6.0\n" + |
||||
"\tGone with the Wind\t11.0\n" + |
||||
"Amount owed is 23.0\n" + |
||||
"You earned 4 frequent renter points"; |
||||
String statement = customer1.statement(); |
||||
assertEquals(expected, statement); |
||||
} |
||||
|
||||
//TODO make test for price breaks in code.
|
||||
} |
||||
Loading…
Reference in new issue