The Template method is one of the behavioral patterns described in the book "Elements Of Reusable Object-Oriented Software" by Gamma et. al. It is also known as a pattern that helps encapsulating algorithms so that subclasses can hook themselves right into a computation anytime they want. It is also known as a design principle inspired by Hollywood: "Don't call us, we will call you".
Define the skeleton of an algorithm in an operation, deferring some steps to subclasses. The Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithms structure. (Gamma et.al.)
Let's understand the entire usage of the pattern step-by-step with an example.
Problem Description
We have a remote controller that helps us controlling several households at home, for example TV, refridgerator, music and so on. As in the following figure, we only have 2 buttons for each and every slot, ON and OFF on the remote. On clicking a button, a number of steps are followed in a strict order, in other words steps of an algorithm. In addition, some common checks are also done such as if electricity supply is on or off. These checks are done for each and every household device.
Solution Description
We can define an abstract class that contains a method (template method) that in turn contains a few primitive operations that each subclass must implement. The template method must not be overridden by subclasses. That means the algorithm must not be changed by subclasses or say it should be hidden. Having said that, let's introduce the class diagram for the given problem.
The point to be noted here is that though a complete solution allows low-level component (concrete classes) to hook themselves into the system, its the high-level component that determine when a low-level implementation is required. It is also known as the "Hollywood Principle", in other words Don't call us, we will call you.
Source Code
The following shows the Abstract Template Method:
- public abstract class IAlgorithm
- {
- public abstract void Exceute();
- }
The following shows an abstract class with a few primitives and a Template Method:
- public abstract class ICommand: IAlgorithm {
-
-
-
-
-
- public sealed override void Exceute() {
- IsPowerOn();
- CheckTheStatusOfDevice();
- SwitchOnOffDevice();
- }
-
-
-
-
- private bool IsPowerOn() {
- Console.WriteLine("Yes, Power is on");
- return true;
- }
-
-
-
-
- protected abstract void CheckTheStatusOfDevice();
-
-
-
-
- protected abstract void SwitchOnOffDevice();
- }
- }
Concrete Class
- public class SwitchOnWaschmachine: ICommand {
- private readonly Waschmachine _waschmachine;
- private bool isDeviceOn {
- get;
- set;
- }
- public SwitchOnWaschmachine(Waschmachine waschmachine) {
- _waschmachine = waschmachine;
- }
- protected override void SwitchOnOffDevice() {
- if (isDeviceOn) {
- Console.WriteLine("Device is Already On");
- } else {
- _waschmachine.SwitchOn();
Washmachine
- public bool _deviceStatus {
- get;
- private set;
- }
- internal void SwitchOn() {
- MessageBox.Show("Switching On Washing Machine");
- _deviceStatus = true;
- }
- internal void SwitchOff() {
- MessageBox.Show("Switching Off Washing Machine");
- _deviceStatus = false;
- }
Subclass SwitchOnWaschmachine of ICommand implements all the primitive operations that are part of an algorithm. The algorithm that is implemented in a sealed method "Execute" in the base class. When the Execute method is called, it internally calls all the instance methods and primitives (abstract) methods from subclasses in the order defined. Because it's the method that contains the algorithm, this pattern is called a Template Method.
Conclusion
Since it can be clearly seen from the example that the Template Method enables subclasses hook into the higher level components but its the higher-level component that decides when a lower-level component must be called. That means "Don't call us, we'll calll you".