Objective ๐ฏ
Defines the skeleton/structure of how an algorithm should be executed in the superclass letting the subclasses to override specific steps of the implementation without changing the main structure.
Type โ
โ๏ธBehavioral: Describes how objects interact/communicate between themselves.
โCreational: Describes how to instantiate an object without large and complex.
โStructural: Describes how objects/classes are composed to form larger structures.
UML ๐
Participants ๐
โข AbstractClass:
- Defines abstract primitive operations that can be overridden by subclasses
- Defines the skeleton of the template method
โข ConcreteClass:
- Implements (overrides) the primitive operations from the AbstractClass
Sample Code ๐ฎ
Structural Example ๐๏ธ
public static class TemplateMethodStructural
{
public static void Execute()
{
AbstractClass lAbstractClassA = new ConcreteClassA();
lAbstractClassA.TemplateMethod();
AbstractClass lAbstractClassB = new ConcreteClassB();
lAbstractClassB.TemplateMethod();
}
}
public abstract class AbstractClass
{
public void TemplateMethod()
{
Step1();
Step2();
}
protected abstract void Step1();
protected abstract void Step2();
}
public class ConcreteClassA : AbstractClass
{
protected override void Step1()
{
Console.WriteLine("ConcreteClassA - Step1");
}
protected override void Step2()
{
Console.WriteLine("ConcreteClassA - Step2");
}
}
public class ConcreteClassB : AbstractClass
{
protected override void Step1()
{
Console.WriteLine("ConcreteClassB - Step1");
}
protected override void Step2()
{
Console.WriteLine("ConcreteClassB - Step2");
}
}
Output
Real-world Example ๐ฅ
public static class TemplateMethodPractical
{
public static void Execute()
{
Person lJohn = new John();
lJohn.DisplayDailyActivityTime();
Person lSimon = new Simon();
lSimon.DisplayDailyActivityTime();
}
}
public abstract class Person
{
public void DisplayDailyActivityTime()
{
WakeUp();
EatBreakFast();
if (HasJob())
GoToWork();
HaveLunch();
HaveDinner();
GoToSleep();
}
protected abstract void WakeUp();
protected abstract void EatBreakFast();
protected abstract bool HasJob();
protected virtual void GoToWork() { } // This action will not be mandatory as it depends if the person has job
protected abstract void HaveLunch();
protected abstract void HaveDinner();
protected abstract void GoToSleep();
}
public class John : Person
{
protected override void EatBreakFast()
{
Console.WriteLine("John - EatBreakFast - 06:30:00");
}
protected override void GoToSleep()
{
Console.WriteLine("John - GoToSleep - 22:00:00");
}
protected override void GoToWork()
{
Console.WriteLine("John - GoToWork - 07:00:00");
}
protected override bool HasJob()
{
return true;
}
protected override void HaveDinner()
{
Console.WriteLine("John - HaveDinner - 20:00:00");
}
protected override void HaveLunch()
{
Console.WriteLine("John - HaveLunch - 12:00:00");
}
protected override void WakeUp()
{
Console.WriteLine("John - WakeUp - 06:00:00");
}
}
public class Simon : Person
{
protected override void EatBreakFast()
{
Console.WriteLine("Simon - EatBreakFast - 09:00:00");
}
protected override void GoToSleep()
{
Console.WriteLine("Simon - GoToSleep - 23:00:00");
}
protected override bool HasJob()
{
return false;
}
protected override void HaveDinner()
{
Console.WriteLine("Simon - HaveDinner - 21:00:00");
}
protected override void HaveLunch()
{
Console.WriteLine("Simon - HaveLunch - 13:00:00");
}
protected override void WakeUp()
{
Console.WriteLine("Simon - WakeUp - 08:00:00");
}
}
Output
Source Code ๐ฒ
ย