Today I started reading Martin Fowler’s book about Refactoring. When I saw the example code for the first chapter I was shocked because it wasn’t written in ActionScript but in Java. It was the first time I saw a Java code. So I sat down and tried to understand how the code works. It took at least one hour. After I understood the bigger part I thought why not translate the example into ActionScript syntax. So here is the final result. If you want the code step by step (like in the book) write me a mail.
// ::MOVIE CLASS:: //
function Movie(title, priceCode){
this.$title = title;
this.setPriceCode(priceCode);
}
Movie.CHILDRENS = 2;
Movie.REGULAR = 0;
Movie.NEW_RELEASE = 1;
Movie.prototype.getPriceCode = function(){
return this.$price.getPriceCode();
}
Movie.prototype.setPriceCode = function(arg){
switch(arg){
case Movie.REGULAR:
this.$price = new RegularPrice();
break;
case Movie.CHILDRENS:
this.$price = new ChildrensPrice();
break;
case Movie.NEW_RELEASE:
this.$price = new NewReleasePrice();
break;
default:
trace(”Incorrect Price Code“);
}
}
Movie.prototype.getTitle = function(){
return this.$title;
}
Movie.prototype.getCharge = function(daysRented){
return this.$price.getCharge(daysRented);
}
Movie.prototype.getFrequentRenterPoints = function(daysRented){
return this.$price.getFrequentRenterPoints(daysRented);
}
// ::RENTAL Class:: //
function Rental(movie, daysRented){
this.$movie = movie;
this.$daysRented = daysRented;
}
Rental.prototype.getDaysRented = function(){
return this.$daysRented;
}
Rental.prototype.getMovie = function(){
return this.$movie;
}
Rental.prototype.getCharge = function(){
return this.$movie.getCharge(this.$daysRented);
}
Rental.prototype.getFrequentRenterPoints = function(){
return this.$movie.getFrequentRenterPoints(this.$daysRented);
}
// ::PRICE:: //
function Price(){}
Price.prototype.getFrequentRenterPoints = function(daysRented){
return 1;
}
function ChildrensPrice(){};
ChildrensPrice.prototype = new Price();
ChildrensPrice.prototype.getPriceCode = function(){
return CHILDRENS;
}
ChildrensPrice.prototype.getCharge = function(daysRented){
var result = 1.5;
if(daysRented > 3){
result += (daysRented - 3)*1.5;
}
return result;
}
function NewReleasePrice(){};
NewReleasePrice.prototype = new Price();
NewReleasePrice.prototype.getPriceCode = function(){
return NEW_RELEASE;
}
NewReleasePrice.prototype.getFrequentRenterPoints = function(daysRented){
return daysRented > 1 ? 2 : 1;
}
NewReleasePrice.prototype.getCharge = function(daysRented){
var result = daysRented*3;
return result;
}
function RegularPrice(){};
RegularPrice.prototype = new Price();
RegularPrice.prototype.getPriceCode = function(){
return REGULAR;
}
RegularPrice.prototype.getCharge = function(daysRented){
var result = 2;
if(daysRented > 2){
result += (daysRented - 2)*1.5;
}
return result;
}
// ::CUSTOMER CLASS:: //
function Customer(name){
this.$name = name;
this.$rentals = new Array();
}
Customer.prototype.addRental = function(rental, daysRented){
this.$rentals.push({rental:rental, daysRented:daysRented});
}
Customer.prototype.getName = function(){
return this.$name;
}
Customer.prototype.statement = function(){
return new TextStatement().value(this);
}
Customer.prototype.htmlStatement = function(){
return new HtmlStatement().value(this);
}
Customer.prototype.$getTotalCharge = function(){
var result = 0;
for(var i=0; i < this.$rentals.length; ++i){
var each = new Rental(this.$rentals[i].rental, this.$rentals[i].daysRented);
result += each.getCharge();
}
return result;
}
Customer.prototype.$getTotalFrequentRenterPoints = function(){
var result = 0;
for(var i=0; i<this.$rentals.length; ++i){
var each = new Rental(this.$rentals[i].rental, this.$rentals[i].daysRented);
result += each.getFrequentRenterPoints();
}
return result;
}
// ::STATEMENT CLASS:: //
function Statement(){}
Statement.prototype.value = function(aCustomer){
var result = this.headerString(aCustomer);
for(var i=0; i < aCustomer.$rentals.length; ++i){
var each = new Rental(aCustomer.$rentals[i].rental, aCustomer.$rentals[i].daysRented);
result += this.eachRentalString(each);
}
result += this.footerString(aCustomer);
return result;
}
// ::TEXT STATEMENT CLASS:: //
function TextStatement(){}
TextStatement.prototype = new Statement();
TextStatement.prototype.headerString = function(aCustomer){
return “Rental Record for ” + aCustomer.getName() + “. “;
}
TextStatement.prototype.eachRentalString = function(aRental){
return aRental.getMovie().getTitle() + “ ” + aRental.getCharge() + “ Euro. ”
}
TextStatement.prototype.footerString = function(aCustomer){
return “Amount owed is ” + aCustomer.$getTotalCharge() + “ Euro. ”
+ “You earned ” + aCustomer.$getTotalFrequentRenterPoints() + “ frequent renter points.“;
}
// ::HTML STATEMENT CLASS:: //
function HtmlStatement(){}
HtmlStatement.prototype = new Statement();
HtmlStatement.prototype.headerString = function(aCustomer){
return “Rental Record for ” + aCustomer.getName() + “. “;
}
HtmlStatement.prototype.eachRentalString = function(aRental){
return aRental.getMovie().getTitle() + “ ” + aRental.getCharge() + “ Euro. ”
}
HtmlStatement.prototype.footerString = function(aCustomer){
return “Amount owed is ” + aCustomer.$getTotalCharge() + “ Euro. ”
+ “You earned ” + aCustomer.$getTotalFrequentRenterPoints() + “ frequent renter points.“;
}
// example
FightClub = new Movie(”Fight Club“, Movie.NEW_RELEASE);
Memento = new Movie(”Memento“, Movie.REGULAR);
PalpFiction = new Movie(”Palp Fiction“, Movie.CHILDRENS);
Simon = new Customer(”Simon“);
Simon.addRental(FightClub, 3);
Simon.addRental(Memento, 1);
Simon.addRental(PalpFiction, 8);
trace(Simon.statement() == “Rental Record for Simon. Fight Club 9 Euro. Memento 2 Euro. Palp Fiction 9 Euro. Amount owed is 20 Euro. You earned 4 frequent renter points.“);

2 Responses to “Refactoring: Improving The Design Of Existing Code [Chapter 1]”
Hi simon,
it is funny to see the code. I am just reading the fowler too. A fascinating book!! I also started with ActionScript and try to begin with Java now. A few days ago I started to transcribe Fowlers Java-Examples into Actionscript-Code. When I am through the first capter we should compare and discuss our code !!!!
See you,
marpfei
Hi marpfei,
when you have finished reading, write me a mail. It would be nice to talk about the code with another programmer. I’m looking forward to hear from you.