Example from HeadFirst book.
You have to brew tea and coffee. In general they both have the same steps like boiling water and pour into cup but also they have some different steps e.g adding condiments - for tea we can add lemon, for coffee we can add milk.
So we create a general (template) class CaffeineBeverage
which is abstract:
public abstract class CaffeineBeverage {
public final void prepareRecipe() {
boilWater();
brew();
pourInCup();
addCondiments();
}
abstract void brew();
abstract void addCondiments();
void boilWater() {
System.out.println("Boiling water");
}
void pourInCup() {
System.out.println("Pouring into cup");
}
Notice that pourInCup
and boilWater
are not abstract because they are exactly the same for both tea and coffee.
Now we create Tea
class which extends our general CaffeineBeverage
class and we define behaviour for e.g adding condiments:
public class Tea extends CaffeineBeverage {
@Override
public void brew() {
System.out.println("Steeping the tea");
}
@Override
public void addCondiments() {
System.out.println("Adding Lemon");
}
}
and Coffee
class, which also extends CaffeineBeverage
class:
public class Coffee extends CaffeineBeverage {
@Override
public void brew() {
System.out.println("Dripping Coffee through filter");
}
@Override
public void addCondiments() {
System.out.println("Adding Sugar and Milk");
}
}
and we can create test class for template method design pattern:
public class CaffeineBeverageTest {
public static void main(String[] args){
Tea tea = new Tea();
tea.prepareRecipe();
Coffee coffee = new Coffee();
coffee.prepareRecipe();
}
}
so as being said - create abstract class and methods inside. Use abstract methods for different behavior and normal methods with body for common behaviour.