Template Pattern: Friend or Foe?
April 29, 2008 | 9:26 pmHaving come across Alex Miller’s blog, I’ve enjoyed a number of his posts. However, whereas I am definitely in-line with his dislike of the Singleton pattern, I couldn’t agree with his conclusions on the use of the template pattern.
1. Communicates intent poorly - The template method pattern is often used as part of the effective API in some mini-framework where the framework user is expected to subclass the template class. My experience has been that it is difficult to communicate that usage intent to users of the framework. Often the template class has some non-private methods that are exposed for use by the framework but are not intended to be used by the framework user, some that are intended to be overridden, and some that are both. Also, you may need to say whether the super’s version of the method can, should, or must be called. Communicating all that clearly is impossible in an API of any complexity.
I think that this describes a poorly implemented template. Certainly I agree that the pattern (or any other), can be misused, but when applied correctly I have found it very useful in directing correct usage and taking away the worry that it what needs to be done gets done.
Let me try to concoct some example that is illustrative while not having so many holes in it to detract…
Take the struts Action for example.
It quite conceivable/normal that within an application some high level activities that are common to all actions find their way up into some super class that extends org.apache.struts.action.Action
As a result is is quite common to find implementations of the abstract execute method in Action that look something like
public class NewAction extends TopLevelApplicationAction {
@Override
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
// Do the stuff that must always be done
super();
// Do the stuff that My Action needs to do
while(stuffToDo())
{
doStuff();
}
return mapping.findForward(SUCCESS_FORWARD);
}
I don’t like to see super(). It make me think what’s going on up there (which encapsulation dictates is none of my business) and it also makes me think what if it wasn’t called? This is basically relying on the implementer doing what is expected, rather than the design ensuring that it happens.
And this is where the Template pattern steps up to the mark.
Changing the TopLevelApplicationAction a little…
public abstract class TopLevelApplicationAction extends org.apache.struts.action.Action {
@Override
public final ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
// Do the stuff that must always be done
while(stuffThatMustAlwaysBeDoneToDo())
{
doStuffThatMustAlwaysBeDone();
}
return executeAction(mapping, form, request, response);
}
public abstract ActionForward executeAction(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) throws Exception;
This then constrains this implementation of this and removes the responsibility of calling the super class from the implementer of the specific action.
public class NewAction extends TopLevelApplicationAction {
@Override
public ActionForward executeAction(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
// Do the stuff that My Action needs to do
while(stuffToDo())
{
doStuff();
}
return mapping.findForward(SUCCESS_FORWARD);
}
A bit of a noddy example, but surely that must be better than the first (and in my experience, the most commonly seen) approach!?






Yes, I think your example shows an improvement. However,
Alex Miller | April 30, 2008 | 2:35 pmYes, I think your example shows an improvement. However, my experience has been that classes (and particularly APIs) built on the template method evolve poorly over time. At the beginning, they work great. But over time you keep coming up with new refinements in the templated code and often you start to insert layers of multiple abstract classes, each with their own sets of template methods. I’ve been down this road more than once and it quickly becomes a nightmare.
In general, I find that using composition over inheritance can be just as clear intent-wise plus it evolves in a linear way allowing you to mix and match the functionality you need.
Unfortunately this is a difficult argument to make without showing a whole lot of code or having lived through it yourself.
Unfortunately, I have also witnessed the results of poor evolution... ...and
Ian | April 30, 2008 | 4:49 pmUnfortunately, I have also witnessed the results of poor evolution…
…and I’d also go for composition over inheritance.
Using the template pattern is not an approach I would necessarily design in. As you stated in your post, by using the template pattern you are essentially building a mini-framework and that isn’t something to be undertaken lightly.
Nevertheless, of late I have found myself tackling existing code using existing frameworks that do involve concrete inheritance. Some judicious use of the template pattern, I feel, has helped clean things up, introduce some degree of control and kill a few bugs.
Thanks for the comment (and giving me something to blog about)!