The Template Method design pattern defines the skeleton of an algorithm in an operation, deferring some steps to subclasses. This pattern lets subclasses redefine certain steps of an algorithm without changing the algorithm‘s structure.
A visualization of the classes and objects participating in this pattern.
The classes and objects participating in this pattern include:
DataObject
)
CustomerDataObject
)
This structural code ddemonstrates the Template Method which provides a skeleton calling sequence of methods. One or more steps can be deferred to subclasses which implement these steps without changing the overall calling sequence.
using System;
namespace Template.Structural
{
/// <summary>
/// Template Design Pattern
/// </summary>
public class Program
{
public static void Main(string[] args)
{
AbstractClass aA = new ConcreteClassA();
aA.TemplateMethod();
AbstractClass aB = new ConcreteClassB();
aB.TemplateMethod();
// Wait for user
Console.ReadKey();
}
}
/// <summary>
/// The 'AbstractClass' abstract class
/// </summary>
public abstract class AbstractClass
{
public abstract void PrimitiveOperation1();
public abstract void PrimitiveOperation2();
// The "Template method"
public void TemplateMethod()
{
PrimitiveOperation1();
PrimitiveOperation2();
Console.WriteLine("");
}
}
/// <summary>
/// A 'ConcreteClass' class
/// </summary>
public class ConcreteClassA : AbstractClass
{
public override void PrimitiveOperation1()
{
Console.WriteLine("ConcreteClassA.PrimitiveOperation1()");
}
public override void PrimitiveOperation2()
{
Console.WriteLine("ConcreteClassA.PrimitiveOperation2()");
}
}
/// <summary>
/// A 'ConcreteClass' class
/// </summary>
public class ConcreteClassB : AbstractClass
{
public override void PrimitiveOperation1()
{
Console.WriteLine("ConcreteClassB.PrimitiveOperation1()");
}
public override void PrimitiveOperation2()
{
Console.WriteLine("ConcreteClassB.PrimitiveOperation2()");
}
}
}
This real-world code demonstrates a Template method named Run() which provides a skeleton calling sequence of methods. Implementation of these steps are deferred to the CustomerDataObject subclass which implements the Connect, Select, Process, and Disconnect methods.
using System;
using System.Collections.Generic;
namespace Template.RealWorld
{
/// <summary>
/// Template Design Pattern
/// </summary>
public class Program
{
public static void Main(string[] args)
{
DataAccessor categories = new Categories();
categories.Run(5);
DataAccessor products = new Products();
products.Run(3);
// Wait for user
Console.ReadKey();
}
}
/// <summary>
/// The 'AbstractClass' abstract class
/// </summary>
public abstract class DataAccessor
{
public abstract void Connect();
public abstract void Select();
public abstract void Process(int top);
public abstract void Disconnect();
// The 'Template Method'
public void Run(int top)
{
Connect();
Select();
Process(top);
Disconnect();
}
}
/// <summary>
/// A 'ConcreteClass' class
/// </summary>
public class Categories : DataAccessor
{
private List<string> categories;
public override void Connect()
{
categories = new List<string>();
}
public override void Select()
{
categories.Add("Red");
categories.Add("Green");
categories.Add("Blue");
categories.Add("Yellow");
categories.Add("Purple");
categories.Add("White");
categories.Add("Black");
}
public override void Process(int top)
{
Console.WriteLine("Categories ---- ");
for(int i = 0; i < top; i++)
{
Console.WriteLine(categories[i]);
}
Console.WriteLine();
}
public override void Disconnect()
{
categories.Clear();
}
}
/// <summary>
/// A 'ConcreteClass' class
/// </summary>
public class Products : DataAccessor
{
private List<string> products;
public override void Connect()
{
products = new List<string>();
}
public override void Select()
{
products.Add("Car");
products.Add("Bike");
products.Add("Boat");
products.Add("Truck");
products.Add("Moped");
products.Add("Rollerskate");
products.Add("Stroller");
}
public override void Process(int top)
{
Console.WriteLine("Products ---- ");
for (int i = 0; i < top; i++)
{
Console.WriteLine(products[i]);
}
Console.WriteLine();
}
public override void Disconnect()
{
products.Clear();
}
}
}
The .NET optimized code demonstrates the
same real-world situation as above but uses modern, built-in .NET features,
such as, generics, reflection, LINQ, lambda functions, etc.
You can find an example on our Singleton pattern page.
All other patterns (and much more) are available in our Dofactory .NET product.
Not only does Dofactory .NET cover the Gang of Four and Enterprise patterns, it also includes
pattern architectures, low-code, and RAD (Rapid Application Development) techniques.
Accelerate development to where you can write
entire solutions in just 33 days!.
This unique package will change your developer lifestyle.
Here's what is included: