Template method
RHS – SOC 2
How to make a pizza
• If you order a pizza, the manufacturing of a pizza goes through certain steps
• We can write up a sort of algorithm for making a pizza
RHS – SOC 3
How to make a pizza// From a class PizzamakePizza(){
createDough();rolloutDough();if (mustAddTomatoSauce()) addTomatoSauce();addToppings();if (mustAddCheese()) addCheese();bake();cut();putInBox();
}
RHS – SOC 4
How to make a pizza
• This method for creating a pizza is generic; we always follow this algorithm
• However, not all of the individual steps are generic; they vary with the actual product
• We can categorise the methods, according to their ”genericity”
RHS – SOC 5
How to make a pizzamakePizza(){
createDough();rolloutDough();if (mustAddTomatoSauce()) addTomatoSauce();addToppings();if (mustAddCheese()) addCheese();bake();cut();putInBox();
}
Is a fully generic method for making a pizza
RHS – SOC 6
How to make a pizzamakePizza(){
createDough();rolloutDough();if (mustAddTomatoSauce()) addTomatoSauce();addToppings();if (mustAddCheese()) addCheese();bake();cut();putInBox();
}
The red steps are fully generic – they never vary
RHS – SOC 7
How to make a pizzamakePizza(){
createDough();rolloutDough();if (mustAddTomatoSauce()) addTomatoSauce();addToppings();if (mustAddCheese()) addCheese();bake();cut();putInBox();
}
The green steps may vary, but have a default behavior
RHS – SOC 8
How to make a pizzamakePizza(){
createDough();rolloutDough();if (mustAddTomatoSauce()) addTomatoSauce();addToppings();if (mustAddCheese()) addCheese();bake();cut();putInBox();
}
The brown step will vary, and has no default behavior
RHS – SOC 9
Method categorisation
Method Type Definition OverrideTemplate Method
Defines generic skeleton for algorithm
No
Concrete Operation
Generic algorithm step No
Hook Default – but overridable – algorithm step
May
Primitive Operation
Specialised algorithm step
Must
RHS – SOC 10
Specialised pizza
• How can we then make a specific pizza?• We can let a subclass – e.g HawaiiPizza-
NoCheese specialise the Pizza class• What should this class implement..?• Non-generic steps, i.e
– Hooks– Primitive Operations
RHS – SOC 11
Specialised pizzapublic class HawaiiPizzaNoCheese extends Pizza{
// Hook (overrides default behavior)public boolean mustAddCheese() { return false;}
public void addToppings() // Primitive operation{
addPineAppleSlices();addShrimps();addShreddedHam();
}}
RHS – SOC 12
Template method pattern
AbstractClasstemplateMethod()…primitiveOpA()primitiveOpB()primitiveOpC()
Notice this is not an interface!
ConcreteClassprimitiveOpA()primitiveOpB()primitiveOpC()
templateMethod() is never overwritten!
RHS – SOC 13
Template method pattern
Pizza myPizza = new CopenhagenSpecialPizza();...myPizza.makePizza();
// Notice that Pizza myPizza = new Pizza() // will fail!
RHS – SOC 14
Template method pattern
• What have we achieved?– Program to an interface, not an
implementation• Clients will only know the AbstractClass interface
– Encapsulate the aspects that vary• Specialised algorithm steps are located in the
specialised classes
RHS – SOC 15
Template method pattern
• What have we achieved?– Open for extension, closed for modification
• We can add new specialisations without modification of base
– Don’t call us, we’ll call you• Base class calls specialised steps, not vice versa
• The last principle is called the Hollywood Agent principle
RHS – SOC 16
Template method pattern
BaseMakePizza
Spec.
AddToppings()
Base
Spec.MakePizza
CreateDough()
Don’t call us, we’ll call you- High-level classes are in control- Low-level classes can be hooked onto a system- Low-level classes don’t call high-level classes directly
RHS – SOC 17
Exercises• Download the NetBeans project TemplateMethodExample from the Website
(go to Classes, Week 43)• Examine the code; the class Pizza implements a template method
makePizza for making a pizza. The template method contains concrete operations, hooks and primitive operations
• Recall that hooks may – and primitive operations must – be overrided in specialised classes. Two such classes have been added; HawaiiPizza and VegetarianPizza. Examine their implementation.
• A test of making concrete pizzas is found in Main. Try it out! Notice how you just call makePizza on the specialised class objects, in order to make a specific pizza
• Try adding a couple of additional specialised pizza classes to the project, and add tests of them to the test.