Template Pattern - Friend or Foe?

Having 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!?

comments powered by Disqus