Template Pattern C#
Contents
- What Is Template Method Pattern?
- Template Method Pattern C# Example
- Where To Apply Template Method Pattern?
- Further Reading
What Is Template Method Pattern?
The Template Method pattern in C# enables algorithms to defer certain steps to subclasses. The structure of the algorithm does not change, but small well-defined parts of its operation are handled elsewhere.
Template Methods are very useful in conjunction with the Strategy pattern. Any system that wishes to defer primitive operations to other classes will benefit from this pattern. In C#, it is used extensively through predefined interfaces.
The Template Method pattern defines the skeleton of an algorithm in an operation, deferring some steps to subclasses. Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithm’s structure.
Template Method Pattern C# Example
Let’s start with the problem statement,
Let say you are creating a library of algorithms for C# developers that contain all type of sorting algorithm. One of the algorithms would be Merge Sort like this:
Now you don’t have to know the code for the Merge Sort, it’s only going to be here to prove a point.
Let’s see how clients will use our above class,
Everything looks cool in the above program right! If we run the above program we will get the following output.
Now,
Here’s my problem, it only stores int.
What if our clients want to use a different data type like float or string or any user-defined type like below one, a Person type.
Also, what if I have to sort the list of person based on its age or name.
One thing we can do is make our MergeSort algorithm generic like this,
Note: You can learn more about Generic Types in my blog post Generics In C#.
After we make this adjustment you will find that there would be a compile-time error
So, how to solve this?
As I mentioned earlier, In C#, the template method is used extensively through predefined interfaces, one such interface is IComparable
.
In the above sort method, the compare operations can replace <=
operator with the primitive operation CompareTo, as in:
CompareTo is a method that returns 1 if a>b
, 0 if a==b
, and -1 if a<b
.
It is defined in the IComparable
interface, which many predefined C# types already implement. For example, CompareTo is available for integers and strings. Because our sort methods are meant
to be general, we declare that the item types must implement the interface using:
The where clause puts a constraint on the type <T>
by saying it must implement
IComparable
. Any class can do so if it provides a CompareTo method. So,
inside a Person class, we have to implement the IComparable
interface like this:
But how is CompareTo defined in terms of CompareTo? Well, we are looking at names, so the name will presumably be a string. CompareTo is defined for strings so that is what will be called. The check for the type of the object is necessary because the implementation of CompareTo must match its interface, which is defined on the object.
Let’s see how clients can use our new update merge sort class,
If we run the above program we will get the following output:
When a Template Method uses an interface for specifying the primitive operations, the classes must implement those operations. It is also possible to define IPrimitives as an abstract class and to provide default behavior for any of the operations, leaving the subclass to override as many operations as it wishes. Methods that have defaults are called hook operations, and they often do nothing by default.
Where To Apply Template Method Pattern?
-
When you need to implement the invariant parts of an algorithm once and leave it up to subclasses to implement the behavior that can vary.
-
When common behavior among subclasses should be factored and localized in a common class to avoid code duplication. This is a good example of “refactoring to generalize” as described by Opdyke and Johnson in their research paper Creating Abstract Superclasses by Refactoring. You first identify the differences in the existing code and then separate the differences into new operations. Finally, you replace the differing code with a template method that calls one of these new operations.
-
When you need to control subclasses extensions. You can define a template method that calls “hook” operations at specific points, thereby permitting extensions only at those points.
The Template Method pattern is more like the Strategy pattern in that it is algorithm-based. The steps of the algorithm are specified in the Template Method and some are deferred to domain classes.
Note: You can download the complete solution demo from my github repository.
Further Reading
-
Strategy Pattern C# - The Strategy pattern in C# lets the algorithm vary independently from clients that use it. The Strategy pattern enables a client to choose which algorithm to use from a family of algorithms and gives it a simple way to access it.
-
Template Method Pattern. Can we do better? by Leif Battermann - In this post, Leif compare the application of the Template Method pattern to an alternative approach adopted from functional programming. This alternative approach made use of higher-order functions. Even though this example is kind of simple and bold it demonstrates that the functional way may lead to cleaner and more maintainable code in some situations.
-
Curiously recurring template pattern by Guillermo Subirán - In this post, Guillermo explains the curiously recurring template pattern (CRTP) which is an idiom in C++ in which class X derives from a class template instantiation using X itself as a template argument. More generally it is known as F-bound polymorphism, and it is a form of F-bounded quantification. The idea of CRTP is similar to the template method pattern we discussed in this post.
Subscribe to Code with Shadman
Get the latest posts delivered right to your inbox