Initial commit

master
Thomas Clavier 8 years ago
commit d6e078bf3d
  1. 34
      README
  2. 20
      pom.xml
  3. 64
      src/main/java/movierental/Customer.java
  4. 29
      src/main/java/movierental/Movie.java
  5. 23
      src/main/java/movierental/Rental.java
  6. 30
      src/test/java/movierental/CustomerBuilder.java
  7. 104
      src/test/java/movierental/CustomerTest.java

@ -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…
Cancel
Save