Time for yet another pattern, the Template Method Pattern. Have a look at all the other patterns in the series as well.

The definition: "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."

Let's add an additional requirement to our game. We need different types of renderers for our GUI, the main screen is in 3D, while the map is displayed in 2D.

Both layouts follow a specific drawing order. First the background, then the units, on screen instructions, special effects and a border. If this order is wrong, it would be possible for the background to overlap the units, which we don't want.

We'll start by creating a new base class for our renderers, with some abstract methods which make up the algorithm of drawing the screen.

Base Class

As you can see, there are two non-abstract methods. DrawBorder() which is common functionality for every render and RenderScreen() which is actually a Template Method.

The Template Method defines the steps used in the algorithm, without actually implementing the steps itself.

Template Method

As you can see from the comments, with the perfect implementation, RenderScreen() should be a method which can't be overridden by child classes. C# doesn't support this however.

When we create our two renderers and have the discipline to not hide RenderScreen(), the class diagram for the Template Method Pattern looks like this:

Class Diagram Template Method Pattern

If we test this code, we notice that the order of rendering a screen is the same, but that each engine implements the steps differently, or not at all.

Testing Template Method Pattern

And that's the Template Method Pattern! I've uploaded the solution again to have a look at.

Some additional information on the Template Method Pattern:

 
Reacties: 5
 
  • Hi David, your example is wonderful and so lucky that find your blog. I will read all your
    articles about design pattern. Thank you so much:))

     
     
  • Hey David, thanks for the great series. Only problem is that i'm now even less pushed to read an actual programming book :)

    BTW, your derived renderers cannot hide RenderScreen because that method is not virtual. If it was, they could override it.

    About the meeting people thing, i would say try to also get in touch with other geeks in your neighborhood, maybe a local user group / programming club (not sure what the right word is). I think a dialog is more fun when you're talking face to face.

    I love to hang out with not geeky friends personally, it gives me a break from all the programming stuff. My problem is mostly with time management, i get caught up in programming to much, and don't see my friends enough.

    Ha ik kom er net achter dat je Vlaming bent! Zelf studeer ik geneeskunde in Nederland, heerlijke combi. Ow en ik haal 40 push ups ;)

    Succes!

     
     
  • Hi Alvin,

    Well, that's the point really, they shouldn't be hiding RenderScreen() at all, since it's the base class which provides the template for it.

    They are free to implement the individual steps however.

    ---
    Ah, but now I see what you meant, because I mentioned "hide" in my post. Well, if you don't have discipline in your subclass you could do "public new void RenderScreen()" to hide it. That's what I meant ;)

    ---
    Pushups, pfffff, I can never make the time to stick to it :p

     
     
  • "your subclass you could do “public new void RenderScreen()” to hide it". It could do that, but it would never get called since the client code only uses the base class, and calls RenderScreen() on that class.

    Found this on google: http://blogs.msdn.com/csharpfaq/archive/2004/03/12/88453.aspx

    BTW, are you familiar with the ALT.net people? Ayende Rahien for example, he wishes everything is virtual by default :)

     
     
  • That's true, but that's the whole point of a Template Method Pattern I thought, having your base class control the algorithm order, and not allowing your subclasses to override it. Doesn't making it virtual kinda defeat that point/control?

    I'm familiar with them, Ayende is in the list of blogs I daily read :)

     
     
  • Reageer
    Items aangeduid met * zijn verplicht. (Naam, Email, Commentaar)
    Enkele items ontbreken of zijn fout ingevuld.
     
     
     
    Om zeker te zijn dat je geen computer bent, typ de onderstaande tekst over.