import testing.*; class Pizza { ToppingList toppings; boolean deepDish; Pizza( ToppingList toppings, boolean deepDish ) { this.toppings = toppings; this.deepDish = deepDish; } // new Pizza(new EmptyTL(), true).superSizeMe() -> new Pizza(new EmptyTL(), true) //new Pizza(new LargerTL(new GreenPepper(.3), new EmptyTL()), // true).superSizeMe() -> new Pizza( new LargerTL( new GreenPepper(.6), new EmptyTL()), true) //To produce a supersizing of this Pizza Pizza superSizeMe() { // ... this.deepDish ... this.toppings.ToppingListMethod() ... return new Pizza( this.toppings.superSizeAll(), this.deepDish); } //new Pizza(new EmptyTL(), true).fullPrice() -> 4.5 //new Pizza(new LargerTL(new Pepperoni(1),new EmptyTL()), false).fullPrice() -> 3.1 //To calculate the total price of this Pizza double fullPrice() { // ... this.deepDish ... this.toppings.ToppingMethod() ... return this.basePrice() + this.toppings.totalPrice(); } //new Pizza(new EmptyTL(), false).basePrice() -> 3.0 //new Pizza(new EmptyTL(), true).basePrice() -> 4.5 //To calculate the price of this Pizza without regard for toppings double basePrice() { // ... this.toppings.ToppingListMethod() ... this.deepDish ... if (this.deepDish) return 4.5; else return 3.0; } } abstract class Topping { //To calculate the price of this Topping abstract double price(); //To produce a supersized version of thie Topping abstract Topping superSize(); } class GreenPepper extends Topping { double amt; GreenPepper(double amt) { this.amt = amt; } //new GreenPepper(1.0).price() -> .75 //To calculate the price of this GreenPepper double price() { //... this.amt ... return this.amt * .75; } // new GreenPepper(2.5).superSize() -> new GreenPepper(5.0) //To produce a supersized version of this GreenPepper Topping superSize() { // ... this.amt ... return new GreenPepper(this.amt*2); } } class Pepperoni extends Topping { int slices; Pepperoni(int slices) { this.slices = slices; } //new Pepperoni(1).price = .1 //To calculate the price of this Pepperoni double price() { // ... this.slices ... return this.slices * .1; } // new Pepperoni(6).superSize() -> new Pepperoni(12) //To produce a supersized version of this Pepperoni Topping superSize() { // ... this.slices ... return new Pepperoni( this.slices * 2 ); } double superSizedPrice() { return this.superSize().price(); } } //... this.superSize().price() abstract class ToppingList { //To calculate the total price of this ToppingList abstract double totalPrice(); //To produce a supersizing of this ToppingList abstract ToppingList superSizeAll(); } class EmptyTL extends ToppingList { EmptyTL() { } //new EmptyTL().totalPrice() -> 0 //To calculate the total price of this EmptyTL double totalPrice() { // ... return 0; } // new EmptyTL().superSizeAll() -> new EmptyTL() //To produce a supersizing of this EmptyTL ToppingList superSizeAll() { // .... return this; } } class LargerTL extends ToppingList { Topping front; ToppingList rest; LargerTL( Topping front, ToppingList rest ) { this.front = front; this.rest = rest; } //new LargerTL(new GreenPepper(2.0), new LargerTL( new Pepperoni(5), new EmptyTL())).totalPrice() -> 2.0 //To calculate the total price of this LargerTL double totalPrice() { // ... this.front.ToppingMethod() ... this.rest.ToppingMethod() ... return this.front.price() + this.rest.totalPrice(); } //new LargerTL( new GreenPepper(3.0), new EmptyTL()).superSizeAll() -> // new LargerTL( new GreenPeppe(6.0), new EmptyTL() ) //To produce a supersizing of this LargerTL ToppingList superSizeAll() { // ... this.front.ToppingMethod() ... this.rest.ToppingListMethod() ... return new LargerTL( this.front.superSize(), this.rest.superSizeAll() ); } } class PizzaTest extends Test { PizzaTest() { } TestResult testPizzaNoToppingsPrice() { return this.compareInexacts( new Pizza(new EmptyTL(), true).fullPrice(), 4.5, 0.1); } TestResult testPizzaSomeToppingsPrice() { return this.compareInexacts( new Pizza(new LargerTL(new Pepperoni(1),new EmptyTL()), false).fullPrice(), 3.1, 0.1); } TestResult testBasePriceThin() { return this.compareInexacts(new Pizza(new EmptyTL(), false).basePrice(), 3.0, 0.1); } TestResult testBasePriceDeepDish() { return this.compareInexacts(new Pizza(new EmptyTL(), true).basePrice(), 4.5, 0.1); } }