Introduction to Template Method Pattern

In this article, I am going to discuss about Template Method pattern. This pattern helps us to improve code reusability. Without this pattern, it may require to write duplicated code in many subclasses. It is very helpful in designing frameworks. This pattern defines the skeleton of a method/operation and allowing subclasses to define some steps of it. Template methods allow subclasses to redefine few of the steps of a method/algorithm without changing its structure/flow. The main theme behind this pattern is to give a chance to subclasses for redefining few operations/methods. I am going to explain this pattern with an example.

Scenarios applicable for using this Pattern:

  • To reduce replicated code in subclasses.
  • To maintain the code properly for easy modifications.

Benefits of using this Pattern:

  • To improve Code Reusability.
  • Helpful in designing Frameworks.

Participants in this Pattern:

  • Abstract Class: This class defines virtual and template methods. This template method will have calls to methods defined in concrete subclasses.
  • Concrete Class: This class defines the methods inherited from base class along with definition to its internal members.

Implementation:

This example explains about Template Method Display(), which is having a skeleton calling a series of methods. Implementation of some of the methods is given to its subclasses.

Create a new console application and name it as TemplatePatternSample. Now, add the code to program.cs as shown below:

First, I am defining Employee & Department classes [DTO] as shown below:

#region DTO Defns
    class Employee
    {
        public int EmpID { get; set; }
        public string EmpName { get; set; }
        public string Salary { get; set; }
        public Employee(int empID, string empName, string sal)
        {
            this.EmpID = empID;
            this.EmpName = empName;
            this.Salary = sal;
        }
    }
    class Department
    {
        public int DeptID { get; set; }
        public string DeptName { get; set; }
        public string Location { get; set; }
        public Department(int deptID, string deptName, string loc)
        {
            this.DeptID = deptID;
            this.DeptName = deptName;
            this.Location = loc;
        }
    }
    #endregion

Now, we will define the abstract class named as AbstractDAO:

    #region Abstract Class
    abstract class AbstractDAO
    {
        public abstract void LoadDetails();
        public abstract void FormatAndDisplayDetails();
        public virtual void StartUp()
        {
            Console.WriteLine("Start of Processing");
            Console.WriteLine("-------------------");
        }
        public virtual void Dispose()
        {
            Console.WriteLine("End of Processing");
        }
        public void Display()
        {
            StartUp();
            LoadDetails();
            FormatAndDisplayDetails();
            Dispose();
        }
    }
    #endregion

Here, we defined Display() method with a series of method calls. LoadDetails() and FormatAndDisplayDetails() are declared as abstract making it to redefine in its subclasses.

We will define two concrete subclasses for AbstractDAO as shown below:

     #region Concrete Classes
    class Employees : AbstractDAO
    {
        private List<Employee> empList = new List<Employee>();
        public override void LoadDetails()
        {
            //Get Data From Database.
            empList.Add(new Employee(10,"TEST","2000"));
            empList.Add(new Employee(20,"TEST1","3000"));
            empList.Add(new Employee(30, "TEST2", "4000"));
        }

        public override void FormatAndDisplayDetails()
        {
           //Add $ to Salary
            foreach (Employee emp in empList)
            {
                emp.Salary = "$" + emp.Salary;
                //Display all Employees Details.
                Console.WriteLine("Employee ID: " + emp.EmpID);
                Console.WriteLine("Employee Name: " + emp.EmpName);
                Console.WriteLine("Employee Salary: " + emp.Salary);
                Console.WriteLine("-------------------");
            }
        }
    }
    class Departments : AbstractDAO
    {
        private List<Department> deptList = new List<Department>();
        public override void LoadDetails()
        {
            //Get Data From Database.
            deptList.Add(new Department(1000, "HRA", "BLORE"));
            deptList.Add(new Department(2000, "FIN", "HYD"));
            deptList.Add(new Department(3000, "MARKETING", "DEL"));
        }

        public override void FormatAndDisplayDetails()
        {
            //Expand Location.
            foreach (Department dept in deptList)
            {
                if (dept.Location == "BLORE")
                {
                    dept.Location = "BANGALORE";
                }
                else if (dept.Location == "HYD")
                {
                    dept.Location = "HYDERABAD";
                }
                else
                {
                    dept.Location = "DELHI";
                }
                //Display all Departments Details.
                Console.WriteLine("Department ID: " + dept.DeptID);
                Console.WriteLine("Department Name: " + dept.DeptName);
           Console.WriteLine("Department Location: " + dept.Location);
                Console.WriteLine("-------------------");
            }
        }
    }
    #endregion

In LoadDetails(), I am loading Employees and Departments details. Later, I am doing format and display of those details in FormatAndDisplayDetails(). We will test it out by calling those methods in Main method as shown below:

        static void Main(string[] args)
        {
            //Call Employees.
            AbstractDAO employees = new Employees();
            employees.Display();
            //Call Departments.
            AbstractDAO departments = new Departments();
            departments.Display();
            Console.ReadLine();
        }

Based on Instance type, AbstractDAO class will call corresponding methods of Employee or Department class. Here, I am displaying employee's details followed by department's details. Now, run the application and the output will be as shown below:



I am ending up the things here. I am attaching source code for reference. I hope this article will be helpful for all.


Similar Articles