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