diff --git a/refactoring-movie/movie.ts b/refactoring-movie/movie.ts index 9bc0c14..cca505e 100644 --- a/refactoring-movie/movie.ts +++ b/refactoring-movie/movie.ts @@ -1,72 +1,56 @@ export class Customer { - name: string; rentals: Rental[] = []; - constructor(private objMovie: Movie) { - } - - getName() { - return this.name; - } + constructor(private name: String) { } addRental(rental: Rental) { this.rentals.push(rental); } - statement() { + generateReport() { let totalAmount = 0; let frequentRenterPoints = 0; - let result = 'Rental record for ' + this.getName() + '\n'; - for (let i = 0; i < this.rentals.length; i++) { - let amount = 0; - const element = this.rentals[i]; - switch (element.getMovie().getPriceCode()) { - case this.objMovie.REGULAR: - amount += 2; - if (element.getDaysRented() > 2) { - amount += (element.getDaysRented() - 2) * 1.5; - } - break; - case this.objMovie.NEW_RELEASE: - amount += element.getDaysRented() * 3; - break; - case this.objMovie.CHILDREN: - amount += 1.5; - if (element.getDaysRented() > 3) { - amount += (element.getDaysRented() - 3) * 1.5; - } - break; - } - - // add frequent renter points - frequentRenterPoints++; - - // add bonus for a two day new release rental - if (element.getMovie().getPriceCode() == this.objMovie.NEW_RELEASE && element.getDaysRented() > 1) { - frequentRenterPoints++; - } + this.rentals.forEach(rental => { + const amount = rental.getRentalAmount(); + frequentRenterPoints += rental.getRenterPoints(); + + totalAmount += amount; + }); + + ReportGenerator.generateReport(this.name, this.rentals, totalAmount, frequentRenterPoints); + } +} + +class ReportGenerator { + static generateReport(name: String, rentals: Rental[], totalAmount, frequentRenterPoints) { + + let result = 'Rental record for ' + name + '\n'; + + rentals.forEach(rental => { + const amount = rental.getRentalAmount(); // show figures for this rental - result += '\t' + element.getMovie().getTitle() + '\t' + amount.toString() + '\n'; + result += '\t' + rental.getMovieTitle() + '\t' + amount.toString() + '\n'; totalAmount += amount; - } + }); result += 'Amount owed is ' + totalAmount.toString() + '\n'; result += 'You earned ' + frequentRenterPoints.toString() + ' frequent renter points'; return result; } - } -export class Movie { - CHILDREN: number = 2; - REGULAR: number = 0; - NEW_RELEASE: number = 1; +interface Movie { + getTitle(): string; + getPoints(days: number): number; + calculateRentalAmount(days: number): number; +} +export abstract class MovieClass { title: string; priceCode: number; @@ -86,18 +70,56 @@ export class Movie { } } +class RegularMovie extends MovieClass implements Movie { + getPoints(days: number): number { + return 1; + } + calculateRentalAmount(days: number) { + let amount = 2; + if (days > 2) { + amount += (days - 2) * 1.5; + } + return amount; + } +} +class NewReleaseMovie extends MovieClass implements Movie { + getPoints(days: number): number { + return days > 1 ? 2 : 1; + } + calculateRentalAmount(days: number) { + return days * 3; + } +} + +class ChildrenMovie extends MovieClass implements Movie { + getPoints(days: number): number { + return 1; + } + calculateRentalAmount(days: number) { + let amount = 1.5; + if (days > 3) { + amount += (days - 3) * 1.5; + } + return amount; + } +} + + export class Rental { - movie: Movie; daysRented: number; - constructor() { + constructor(private movie: Movie) { + } + + getRentalAmount(): number { + return this.movie.calculateRentalAmount(this.daysRented); } - getMovie() { - return this.movie; + getRenterPoints(): number { + return this.movie.getPoints(this.daysRented); } - getDaysRented() { - return this.daysRented; + getMovieTitle(): string { + return this.movie.getTitle(); } } \ No newline at end of file