Skip to main content

Command Palette

Search for a command to run...

Template Method - Design Pattern

Software Architecture Simplified

Updated
3 min readView as Markdown
Template Method - Design Pattern
V

I am a software engineer with over 10 years of experience in a huge variety of projects and architectures, some simple others considerably complex.

Some of my main skills include Software Architecture, Web Development, ASP.NET Core, React.js, Entity Framework Core, Javascript, SQL and Web Services.

I consider myself passionate about coding as I really fell excited about learning technologies and using them to automate and improve processes.

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 📐

image.png

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 🏛️

image.png

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

image.png

Real-world Example 🔥

image.png

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

image.png

Source Code 🎲

https://github.com/VictorLins/DesignPatterns