Patterns I Hate #2: Template Method

39

In the first episode of this series I explored the Singleton pattern and why it sucks. In this episode, I take aim at the Template Method pattern.

To refresh your memory, the Template Method pattern is when you encapsulate the outline of an algorithm or lifecycle in an abstract class, but define certain specific steps as abstract methods. This class then forms a “template” that others can subclass, only supplying the details that are different.

So, you might have a template class and subclasses like this:

public abstract class ConnectionPool {
  ...

  // Public API
  public Connection obtain() { ... }
  public void release(Connection conn) { ... }

  // template methods
  protected abstract Connection createConnection();
  protected abstract boolean isAlive(Connection connection);
  protected abstract void closeConnection(Connection connection);
}

In this API, the ConnectionPool has public methods for users to obtain and release connections as they use them. The ConnectionPool maintains a pool of connections, but creates, closes, and verifies the health of the Connections via the template methods. Framework users would subclass ConnectionPool and add logic to create connections in a system-specific way.

Why is Template Method Evil?

  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.
  2. Difficult to compose functionality – When inheritance is used as the way to add new functionality, it becomes impossible to add functionality in more than one axis at the same time without defining more and more classes. So, say you have a ConnectionPool and you start by having an OracleConnectionPool and DB2ConnectionPool and so on. But then you also need the ability to create XAConnections sometimes. So you then need to create OracleXAConnectionPool and DB2XAConnectionPool and so on. The per-DB pools share some functionality and the XA pools share functionality but can’t inherit from both. This typically leads to a lot of duplication and an explosion in implementations.
  3. Difficult to comprehend program flow – In my experience it takes very few levels of template methods and inheritance to make debugging or understand the sequence of method calls difficult (as few as 2 or 3). When template methods are really pushed (lots of abstract methods at multiple levels), it can become painful to debug this kind of a system.
  4. Difficult to maintain – Having maintained a couple chunks of code that made extensive use of the template method, it can be challenging. This kind of system can rapidly become fragile. Changes at any one level can disturb operation above or below that level in the template methods. There is often a feeling of unpredictability when adding new functionality as it difficult to predict how behavior will change in all cases. You often also tend to build finer and finer tweaks by splitting the algorithmic parts of the template class and inserting more layers, thus exacerbating the problem.

What’s the alternative?

Usually, the best way to address the addition of functionality in orthogonal domains under a template class is to define an interface for each kind of functionality and inject an instance for each. Typically these interfaces are factories and strategies. You can then mix and match each piece separately and also insert interceptors to handle functionality like logging, pooling, caching, etc. This lets you assemble a particular instance of the main class with exactly the mixture of pluggable elements to satisfy your needs. In general, I find this to be easier to understand, more flexible, and more maintainable.

For the example above, you might instead change this to:

public class ConnectionPool {
  private ConnectionFactory connFactory;
  public ConnectionPool(ConnectionFactory factory, EvictionPolicy policy, ...) {
    // store subcomponent instances
  } 

  // Public API is the same, template methods are gone
}

// Move template methods into a pluggable factory
public interface ConnectionFactory {
  Connection createConnection();
  boolean isAlive(Connection connection);
  void closeConnection(Connection connection);
}

Thanks for reading. After Singleton and Template Method, my level of hate goes down quite a bit, so I suspect the next victims selections for this series will be more of the love/hate variety.

Comments

39 Responses to “Patterns I Hate #2: Template Method”
  1. Hi,

    Agreed with the problems of Template Method, I didn’t like it very much myself. I do have a question about the alternative you suggest however, what if I need a sub component that is absent from the super class?

  2. M Easter says:

    +1 on this series, in general, Alex. I especially like that you offer alternatives. If only all tech blog posts were so well thought-out.

  3. A Template method is one of the ways to ‘inject’ a method in an object. Another example is a policy/strategy and in the near future we will also have closures.

    So I like multiple techniques to choose from. And although template methods are not something a design on a daily basis, a lot of frameworks make good use of it (for example the callback functions in Spring)

  4. I have seen many good applications of the template method pattern and do not necessarily consider it an evil. This pattern is very useful when you would like to have a final method describe the flow of the algorithm, with injectable and customizable hot spots. With full blown closures, of course, we will have better alternatives. But with the current machinery in Java, template methods solve a specific problem quite nicely.

  5. Ramon Leon says:

    I think template method is getting a bad rap here, it actually sounds more like you’re following the sound advice of preferring delegation over inheritance. It creates more composable solutions.

    The second piece of good advice that can be applied is to prefer shallow hierarchies over deep ones, which is really what you’re blaming template methods for.

    Template method is an innocent victim of misuse and overuse of inheritance.

    Keep up the series though, nice reads.

  6. Mike Weller says:

    Great post(s) so far – especially because you offer alternatives. I can see both #1 andd #2 in the code base we have here at work, and you’ve got me thinking.

  7. Tomas says:

    Overall, I agree. However, I find the template method useful when:

    * The behavioural difference you are trying to capture must needs reside inside of a big invariant part (obviously)
    * The implementations of the overridden functions requires access to protected functions / data of the base class

    The second part (access to protected data) implies that the template method is less suited for a user of a framework, and more as an internal implementational detail.

  8. Alex says:

    @Muhammad: If your main class is not set up to handle the subcomponent you need, then clearly you need to change it to allow for that functionality. This is true in the case of either a template or non-template design. In the template case, it often ends up implying a slew of new concrete classes or changes to many concrete classes. In the case of a class built with composition, all the existing subcomponents are (likely) unchanged. Depending how you add the new dependency, you may even be able to do so without affecting callers (helps to use a builder or factory to construct the main compositional class if you want this).

  9. Alex says:

    @Peter, Debasish: I agree that if we had closures in Java (don’t hold your breath), that would be another great alternative.

  10. Alex says:

    @Ramon: Absolutely, the meta-point here is to prefer composition/delegation over inheritance. The problem with the template method is that by its nature, it promotes false is-a hierarchies and deep hierarchies. So, while it can be used safely in a controlled environment, I have frequently seen it lead to a lot of ugly code. It’s seductive at first, but I have found it to degrade quickly over time.

  11. Alex says:

    @Tomas: Yes, access to protected data is one concern. However, I’d suggest that if you are providing access to this data through the template class, then you could also provide it in the form of an interface to components that are plugged into a main process class.

    So, something like:

    public abstract class Template {
       // template methods
       protected abstract Thing createThing();
    
       // access to internal protected state
       protected Foo getFoo();
       protected Bar getBar();
    }
    

    can easily be turned into:

    public interface InternalData {
       Foo getFoo();
       Bar getBar();    
    }
    
    public class ThingFactory {
        void init(InternalData data);
        Thing createThing();
    }
    
    public class Process {
        private InternalData data;
        private ThingFactory factory;
    
        public void setThingFactory(ThingFactory t) {
            t.init(data);
        }
    }
    

    Hope that was enough detail to get the idea; this is hard to do in miniature. I’ll contend that in the long run, this design will evolve more cleanly and with less pain than the template method version.

  12. Jude says:

    I dont entirely agree with you. When used propery along with dependency injection ( e,g your factory example and strategy ) it can be quite helpful . It depends on how well you use it .

    After all its just a pattern , it has to be matched to the right situation for effective usage

  13. csharper says:

    Quote Alex “Absolutely, the meta-point here is to prefer lcomposition/delegation over inheritance.” ;)
    -right on the head

    Never extend a concrete class; prefer injected functoids or command objects as Alex states

    Protected data is a bad smell, listen to Alex

  14. BlogReader says:

    I take it then that Spring’s Controllers (SimpleFormController extends AbstractFormController that extends BaseCommandController, AbstractController, WebContentGenerator, WebApplicationObjectSupport, ApplicationObjectSupport. Yes that’s 6 layers deep) is an example of horrible design?

    http://static.springframework.org/spring/docs/2.0.x/api/org/springframework/web/servlet/mvc/SimpleFormController.html

  15. Doug Clinton says:

    I’m not sure I really agree with the whole premise of these articles. Any pattern is subject to a variety of forces in the system in which it is used. There are situations in which a template method is the simplest, most obvious and most convenient pattern to apply. The objections you raise are valid, but what they really highlight is that any pattern, applied in situations where it is not suited, leads to unclear, hard to maintain code.

    If you start with a template, because that is what the situation warrants, and the forces on the code change, because of changing requirements, then a good programmer will take account of that and refactor to introduce a more appropriate pattern. That doesn’t mean that the new pattern was appropriate in the original context, though.

  16. Alex says:

    @BlogReader: I certainly know far too little about Spring and web stuff in general to comment on the quality of the design. From a brief perusal, I’d say that the Spring javadocs are fantastic in telling you how to interact with these classes, mitigating some of the points I’ve made.

    I think this is a perfect example of how the use of the template method leads to difficulty communicating intent. Notice how much time needs to be spent in the javadoc explaining exactly which of the protected methods and abstract methods should typically be overridden as well as how these methods fit into the overall workflow. Also, please notice the “in addition to the superclass” link which takes you to the parent’s workflow (and so on up the chain), which reveals the true complexity of what you’re hooking into. I’d love to hear from someone that’s been maintaining this what they think of it. I’ve built and maintained stuff like this and it was no fun. I later redesigned stuff into a compositional pattern and had a much better experience.

    I’ve certainly seen this pattern a lot in web page-rendering pipelines. Unfortunately, I’m not well-versed in web frameworks so I can’t really compare alternatives based on real examples. Anyone out there capable of blogging a comparison? I’d love to read that.

  17. Alex says:

    @Doug: I find that Template Method and Singleton are patterns that initially look like a perfect solution, but turn out to have some really bad consequences, often way down the line. I also think that there are almost always ways to avoid using them that yield better designs both initially and over time.

    I still use Template Method occasionally, but I use it very, very carefully and not without the conscious knowledge of what I’m getting into. I’ve given up Singleton though – haven’t used one in years.

  18. csharper says:

    @Alex: How about for your next edition, CallSuper and BaseBean antipatterns to expand on the reasons for this edition (http://en.wikipedia.org/wiki/Software_antipatterns)

    @ all: those two antipatterns are just the tip of the iceberg you are heading towards when you choose Template Method; almost from the beginning it is a terrible choice due to what it implies you are trying to do

  19. Rob says:

    This is babble. The guy who said he was ‘not sure’ about the premise was picking up the scent, just being too polite about it. Your claims are vague and your alternative is a mishmash (that pretends to be prescriptive).

    You should really just list the 23 patterns and put a thumbs up or down next to each then move on.

  20. apy says:

    You might want to do a rendition the uses and abuses of inheritance:
    http://www.gotw.ca/publications/mill06.htm

    I find this is a problem for many Java programmers, “what is composition?”. And they have no interest in reading a C++ paper.

  21. Tom Rossen says:

    Although I agree in general, the combinatorial explosion you describe in point 2 could be prevented by injection (ordinary and XA connection classes) into the subclasses (Oracle and DB2). That said, I would still prefer composition over templates.

  22. CV says:

    Template method pattern is for a scenario (as the name suggests) where there is an invariant overall algorithm with components that can vary. There are still lots of cases in the real world where such a scenario is required. I don’t understand how you can do things differently which would be more simple and elegant. True, one can (and should) use composition/delegation via interfaces for the variable methods but how can you avoid inheritance for the invariant “template” method?

    class Foo {
    public void m() {
    step1();
    step2();
    step3();
    }
    }

    Where will you put m() even if you put step1(), step2(), step3() in an interface ?

    IMO, I would not call this an anti-pattern – misusing this pattern for scenarios which its not intended for is the anti-pattern.

  23. Alex says:

    Well, there are many answers, all of which depend on the actual code in question.

    One option if you put all of the step methods in the same interface:

    class FooController {
    // inject or give it to a static version of m()
    private Foo foo;

    public void m() {
    foo.step1();
    foo.step2();
    foo.step3();
    }
    }

    interface Foo {
    step1();
    step2();
    step3();
    }

    Another option is to break up the step methods into separate interfaces if they need to be mix/matched (phases perhaps).

    Sometimes you can boil the points of variation you need into decorators or interceptors on one or more of the phases/methods.

    There are obviously ways you can nicely use Template Method. The problem I’ve seen in practice, is that the number of ways you can abuse it are vastly greater and worse, seem like a natural evolution from the good ways.

    My experience has been that the pure and simple application does not exist – the world is always uglier in practice (or will become so in your next iteration).

  24. I-Love-Patterns says:

    You recommend to use strategies to be injected to form sort of composite structure where each strategy does “it’s” part. Yes, that’ s a good suggestion. I like Strategies, too.
    But then you might have the state spread over severall objects…what then comes to my mind is Doug Leas book about Concurrent Programming and especially the chapters about confining state. Confining state to an object is as far as I remeber his words a good means to avoid multithread havoc. Therefore a template class is not that bad in that it could be used to confine the state within a single object which in turn controls threadsafety. Just Read his example about Observable-Observer and how those may lead to deadlocks.
    But as always: Such posts like mine here use a lot of “could”, “might” and “should”. I think the GoF guys had taken plenty of time to extract most useful patterns and had discussed stuff over and over again. And I think that they made a good choice of patterns then, that they offered us. But they cannot guarantee for a sound usage of the patterns, that is up to use. And “sound usage” in my eyes means to take pros and cons for a *current design* issue into concideration and is far from rejecting a pattern on a general basis.

  25. Alex says:

    I think this is an interesting point. I haven’t mentioned or considered concurrency at all in the post above, which can be another key consideration in making design choices.

    I think that either the typical Template Method pattern or one composed of strategies can be equally thread-safe. I’m not proposing above that the strategies are dynamic on a per-instance basis, rather you would compose an instance as needed. Once it’s constructed, it can be thread-safe for use.

  26. I-Love-Patterns says:

    Just an amendment to my recent post, because it came to my mind about 5 minutes ago: A rather good real life example of template-pattern is the collection API, to be precise the AbstractXYZ impls, which I would say apply template method in a rather benefiting way: Take a look what http://java.sun.com/j2se/1.4.2/docs/api/java/util/AbstractList.html
    states in it javadoc header about implementation requirements for immutable or immutable lists.

  27. I-Love-Patterns says:

    Little amendment to my todays post, as this just came to my mind about 5 minutes ago: Look at java collection api, to be precise to the AbstractXYZ classes. Read the header, for instance of AbstractList, which tells you about how simple it could be to implement a List…I think this is a good example of template-method pattern.

  28. Alex says:

    I don’t think this would be considered a template method pattern. Usually a template method is described as an algorithm with pluggable steps. Certainly abstract classes are useful.

  29. jneira says:

    Thanks for criticism, i was using the pattern usually as a semiabstract and fast way to reuse algorithms and behaviour. I think the use is controlled: only two or three layers trough one “axis” of abstraction and in internal implementation.
    But i take account of drawbacks, some of them i have started to see in my code. Override is a source of errors

  30. Luke says:

    Thanks, very clear article and examples.

  31. Doug says:

    The templated Policy Pattern is better than interfaces in my experience – less code, strongest types. The main thing that I have learned is that there is no such thing as a thing being universally better or best.

    What’s better, a Lamborghini or a Mack dump truck? Depends on if you need to transport 50000 pounds of dirt!

    What systems seriously expose all this grand composition from interfaces and abstraction technobabble. How many abstract base classes written by someone else have you really inherited and implemented? I don’t know about you, but can’t remember having implemented a base written by someone else – it has always been my own base class and my own implementations, when it fits the problem perfectly. All this interface composition stuff is mostly a bad case of YAGNI; Ya aint gonna need it.
    Solve the problems you actually have using the methods that you feel are the most appropriate, set aside the pedantic attitudes that doing it such and such way is “cooler” or “better”.

Trackbacks

Check out what others are saying about this post...
  1. [...] Pure Danger Tech » Blog Archive » Patterns I Hate #2: Template Method [...]

  2. [...] Apparently my previous pattern posts on Singleton and Template Method hit a nerve based on comments and traffic – thanks for reading! I’m now moving the series from patterns that I hate to patterns that I simultaneous love and hate, because hey, I’m a complicated man (and no one understands me but my woman). [...]

  3. [...] Alex Miller points in his Blog the drawbacks of the Template Method out (see his very cool entry here: Alex Miller – Pattern I Hate #2: Template Method). And although this is not really a Template Pattern in it’s purest form it sure has most of the drawbacks as Alex points out, for instance: [...]

  4. [...] 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. [...]

  5. [...] 2. Then, consider alternatives like strategy, factory or callback. http://tech.puredanger.com/2007/07/03/pattern-hate-template/ Posted 21 May 2008 / C_CPlusPlus / [...]

  6. [...] are two clever blog posts, one about disadvantages of the Template Method pattern, and one mentioning a possible alternative in languages with first [...]

  7. [...] Dat zijn toch 2 geheel verschillende concepten, maar ik vind je uitspraak wel interessant, argumenteer eens? Mja, (eerst effe disclaimer doe dus C#) Meeste projecten die ik doe veranderen de requirements tijdens development Dus met de eerste versie van de requirements is het dan altijd, "ola ik kan hier inheritance gebruiken en ga der een schoon OO design van maken" dan gebeurt het -> change requests "Allez effe wat virtual methods in de base class maken die ik in de sub classes kan overriden." (Dan krijgt ge dus al een half-bakken template pattern) "ah, maar men subclass word ergens gebruikt in een class/form A en daar zou ik andere functionaliteit moeten hebben in men baseclass dan wanneer ik hem in class/form B gebruik." Laten we dat dan maar effe oplossen met een functional pointer naar de baseclass … Uiteindelijk is het gewoon niet meer maintainable, laat staan voor iemand die der de eerste keer doorloopt met debuggen Vooral dus bij de grote classes die zeker zullen wijzigen in de loop van het project doe ik dat liever niet, uiteindelijk hebt ge altijd een template pattern, en dat vind ik voor grote classes met veel functionaliteit niet duidelijk verstaanbaar genoeg voor een nieuwe developer die die code zou moeten bekijken anyway effe gegoogled naar een artikel dat een beetje duidelijker beschrijft wat ik bedoel -> Patterns I Hate #2: Template Method : Pure Danger Tech [...]

  8. [...] to follow – without the help of stepping through the code with a debugger. Alex Miller provides a detailed rundown of the reasons he hates the template method pattern in his [...]