Click here to Skip to main content
6,295,667 members and growing! (13,488 online)
Email Password   helpLost your password?
Development Lifecycle » Design and Architecture » General     Intermediate License: The Code Project Open License (CPOL)

Template Method Design Pattern vs. Functional Programming

By Tuomas Hietanen

An article about Template Method Design Pattern and C# 3.0 (Microsoft .NET Framework 3.5) Functional Programming and Lambda Expressions.
C# 3.0, Windows, .NET 3.5VS2008, Architect, Dev, Design
Posted:7 Nov 2007
Views:16,201
Bookmarked:23 times
Unedited contribution
Announcements
Loading...
 
Search    
Advanced Search
printPrint   Broken Article?Report       add Share
  Discuss Discuss   Recommend Article Email
15 votes for this article.
Popularity: 4.92 Rating: 4.18 out of 5

1
2 votes, 13.3%
2

3
3 votes, 20.0%
4
10 votes, 66.7%
5

Introduction

Design patterns have been one of the main topics in software engineering since the book "Design Patterns: Elements of Reusable Object-Oriented Software" (1995). After that there have been also other books of these "GOF-Patterns", like the top rated "Head First Design Patterns". Most of the patterns are still valid, but some of them have become a bit useless in practical Microsoft .NET � environment. One example is the Iterator-pattern (for handling managed collections) because of .NET 2.0 Generics.

The book Head First Design Patterns describes the Template Method Design Pattern as follows:
"Template Method - Define 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."

Basically this is close to the idea of functional programming, lambda expressions, function pointers, (/functors), etc. (despite that the approach has typically been mathematical). What if we could have template function and give it functions as parameters? Well, in Microsoft .NET 3.5 we can, so there is alternative way to make the same thing as the Template Method Design Pattern.

Template Method Design Pattern in practice

Ok, as if we would like to have a software for� let's say� a recipe-making �software for hot drinks. There are some generic methods like: 1. Boil water, 2. Brew, 3. Pour in cup, 4. Add condiments. So let that be the generic template algorithm.
First, what we need is a unit test. VS2008 unit test is easy to generate and great for debugging. Let the test be something simple like this:

 
//A test for HotDrinks

[TestMethod()]
public void HotDrinkTest1()
{
    List<string> recipe = new List<string>();
 
    Coffee myCoffee = new Coffee();
    recipe.Add("Making coffee...");
    recipe.AddRange(myCoffee.MakeRecipe());
 
    Tea myTea = new Tea();
    recipe.Add("Making tea...");
    recipe.AddRange(myTea.MakeRecipe());
 
    recipe.ForEach(s => Console.WriteLine(s));
    //CollectionAssert.AreEqual(WantedResult.TheRecipe, recipe, "Wrong list!");

}


and we would like it to make a recipe like this:

  • "Making coffee...",
  • "Boiling water" (from template),
  • "Dripping Coffee through filter",
  • "Pouring into cup" (from template),
  • "Adding Sugar"

and

  • "Making tea...",
  • "Boiling water" (from template),
  • "Steeping the tea",
  • "Pouring into cup" (from template),
  • "Adding Lemon"

Now, the "schoolbook"-solution using Template Method Design Pattern will look like this:

Screenshot - image002.jpg

Where custom hot drinks (like Coffee, Tea, etc.) override the needed special functionality from the template algorithm class (abstract class called HotDrink).
The source code will look like this:

 
public abstract class HotDrink {
    //The algorithm

    public List<string> MakeRecipe() {
        List<string> recipe = new List<string>();
        recipe.Add(BoilWater());
        recipe.Add(Brew());
        recipe.Add(PourInCup());
        recipe.Add(AddCondiments());
        return recipe;
    }
 
    public abstract string Brew();
 
    public abstract string AddCondiments();
 
    public string BoilWater() {
        return "Boiling water";
    }
 
    public string PourInCup() {
        return "Pouring into cup";
    }
}


 
//Tea concrete implementation class

public class Tea : HotDrink {
    public override string Brew() {
        return "Steeping the tea";
    }
    public override string AddCondiments() {
        return "Adding Lemon";
    }
}


 
//Coffee concrete implementation class

public class Coffee : HotDrink {
    public override string Brew() {
        return "Dripping Coffee through filter";
    }
    public override string AddCondiments() {
        return "Adding Sugar";
    }
}

That was easy. This is another version of current class diagram:

Screenshot - image004.jpg

Lambda Expression

So, what's wrong with Template Method? Well, one of generally accepted fundamental principle of Object- Oriented design is "Favor Composition Over Inheritance". If the HotDrink �class changes there will be troubles as this was not the most dynamical way. Better design would be looking something like this:


Screenshot - image006.jpg

But this will add more complexity. Could we keep the number of our classes and lines of code low? Let's try another solution, with Microsoft .NET 3.5 Framework new functional programming�
We already have the unit test, and it can be exactly same as in the Template Method Design Pattern unit test! Let's see the template algorithm, the class HotDrink: It will also look much like the same, only there are now parameters for custom functions and the (abstract class) inheritance is left away:

 
public class HotDrink {
    //The algorithm

    public List<string> MakeRecipe(List<Func<string>> CustomMethods) {
        List<string> recipe = new List<string>();
        recipe.Add(BoilWater());
        recipe.Add(CustomMethods[0]());
        recipe.Add(PourInCup());
        recipe.Add(CustomMethods[1]());
        return recipe;
    }
 
    public string BoilWater() {
        return "Boiling water";
    }
 
    public string PourInCup() {
        return "Pouring into cup";
    }

Ok� And now explanation what is "List<Func<string>>":
It's just a list of functions... :-) That Func<string> means a code that we can execute at runtime and the return type for the function is string.

If it would have also input parameters, they would come before the result, so the syntax would be Func<T, T2> where T would be some input type and T2 some return type.

Then those special drinks:

 
//Making tea recipe

public class Tea {
    public List<string> MakeRecipe() {
        List<Func<string>> CustomMethods = new List<Func<string>>(){
            (() => "Steeping the tea"), // same as delegate(){ return "Steeping the tea";}

            (() => "Adding Lemon")      // or could be also external delegates.

        };
        return (new HotDrink()).MakeRecipe(CustomMethods); // for this demo, non-static

    }
}


 
//Making coffee recipe

public class Coffee {
    public List<string> MakeRecipe() {
        List<Func<string>> CustomMethods = new List<Func<string>>(){
            (() => "Dripping Coffee through filter"),
            (() => "Adding Sugar")
        };
        return (new HotDrink()).MakeRecipe(CustomMethods);
    }
}

And that's it. The syntax of List<...>{ �, �, �} is also a new Microsoft .NET 3.5 enhancement called Collection Initializer, just an easier way to fill the list. The syntax (() => "") is lambda expression and means the same than anonymous function delegate(){return "...";} which is like normal function, just typed inline. If method would have much more functionality than just return, then it would be clearer to use (named) delegate. Anonymous delegates won't be visible in the class diagram:

Screenshot - image008.jpg

One more thing, I draw the interface to the picture, but left it temporarily out of here for the similarity. Of course it is always important to use classes through interfaces and not use straight concrete classes, so here you go:

 
public interface IHotDrink{
    List<string> MakeRecipe();
}

and that is also in use in the source code included with this article.

How about the performance?

I used Visual Studio 2008 Beta 2 in Microsoft Virtual PC 2007, so I can't do any reliable performance tests. However, I ran the unit test case over many times and the performance seemed to be quite equal:

Screenshot - image010.jpg

So what's the difference?

  • Possibilities to extend more, uses composition, not inheritance.
  • Lighter to implement as sometimes those Func<>s can be used straight from the code and those Tea and Coffee classes are useless.
  • C# developers are not used to read the new enhancements yet. The code is harder to read.
  • Also harder to get the big picture, because current graphical tools are for Object-oriented design, not for functional programming.

Let's see if Functional Programming is the way of the future. The real best practices always come after some time has passed.

History

2007-11-07: The first version and my first article. :-)

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Tuomas Hietanen


Member
________________________________________


Tuomas Hietanen has a degree of M.Sc in
Information Processing (Artificial Intelligence,
Software Engineering, Telecommunications) and
has worked 8 years in the software industry
mainly designing Microsoft .NET based software.

________________________________________
Occupation: Systems Engineer
Company: A major Finnish financial services company
Location: Finland Finland

Other popular Design and Architecture articles:

Article Top
You must Sign In to use this message board.
FAQ FAQ 
 
Noise Tolerance  Layout  Per page   
 Msgs 1 to 1 of 1 (Total in Forum: 1) (Refresh)FirstPrevNext
GeneralThanks PinmemberKarel Kral2:22 21 Nov '07  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 7 Nov 2007
Editor:
Copyright 2007 by Tuomas Hietanen
Everything else Copyright © CodeProject, 1999-2009
Web18 | Advertise on the Code Project