Abstract Class HouseBuilder
package TemplateMethodPattern; // Abstract class defining the template method abstract class HouseBuilder { // Template method public final void buildHouse() { buildFoundation(); buildStructure(); addRoof(); addWalls(); if (hasGarden()) { addGarden(); } furnishHouse(); } protected abstract void buildFoundation(); protected abstract void buildStructure(); protected abstract void addRoof(); protected abstract void addWalls(); protected void addGarden() { System.out.println("Adding a beautiful garden to the house."); } protected abstract void furnishHouse(); protected boolean hasGarden() { return true; } }
package TemplateMethodPattern; // Concrete subclass providing implementation for building a brick house class BrickHouseBuilder extends HouseBuilder { protected void buildFoundation() { System.out.println("Building a brick foundation for the house."); } protected void buildStructure() { System.out.println("Building the brick structure of the house."); } protected void addRoof() { System.out.println("Adding a brick roof to the house."); } protected void addWalls() { System.out.println("Adding brick walls to the house."); } protected void furnishHouse() { System.out.println("Furnishing the brick house."); } protected boolean hasGarden() { return false; } }
package TemplateMethodPattern; // Concrete subclass providing implementation for building a wooden house class WoodenHouseBuilder extends HouseBuilder { protected void buildFoundation() { System.out.println("Building a wooden foundation for the house."); } protected void buildStructure() { System.out.println("Building the wooden structure of the house."); } protected void addRoof() { System.out.println("Adding a wooden roof to the house."); } protected void addWalls() { System.out.println("Adding wooden walls to the house."); } protected void furnishHouse() { System.out.println("Furnishing the wooden house."); } }
Driver
package TemplateMethodPattern; public class TemplateDriver { public static void main(String[] args) { HouseBuilder woodenHouseBuilder = new WoodenHouseBuilder(); woodenHouseBuilder.buildHouse(); System.out.println(); HouseBuilder brickHouseBuilder = new BrickHouseBuilder(); brickHouseBuilder.buildHouse(); } }
In the example above, the HouseBuilder
is an abstract class that defines the template method buildHouse()
. The template method contains the overall algorithm for building a house and calls several abstract methods such as buildFoundation()
, buildStructure()
, addRoof()
, addWalls()
, and furnishHouse()
. These methods represent specific steps of the house building process that need to be implemented by the subclasses.
The WoodenHouseBuilder
and BrickHouseBuilder
are concrete subclasses of HouseBuilder
that provide their own implementations for the abstract methods. Each subclass implements the specific logic for building a wooden house or a brick house, respectively. The WoodenHouseBuilder
also overrides the hasGarden()
method to indicate that it includes a garden, while the BrickHouseBuilder
overrides it to indicate no garden.
When the buildHouse()
method is called on instances of the concrete subclasses, it executes the overall house building algorithm defined in the base class HouseBuilder
. The specific steps of building the foundation, structure, roof, walls, and furnishing the house are carried out as per the implementation in each subclass.
The base class defines the overall structure of building a house, while allowing subclasses to provide specific implementations for certain steps. This way, the common parts of the algorithm are reused, and the subclasses can customize the building process according to their specific requirements.