views:

503

answers:

3

I have been going back and forth between C# and Java for the last 8 years.

One thing that strikes me is that I have completely stopped using the "Template Method" design pattern in C#. Actually, in C# I Have come to think of this pattern as an anti-pattern.

http://en.wikipedia.org/wiki/Template_method_pattern

Coming back to Java, I find the pattern is alive and kicking. I still think it looks antique, but realise that there's no other way to do this in java. Java looks antique too ;)

Since this is going to come up anyway, Why is it an antipattern ?

  • A lot of times it uses up your inheritance hierarchy for "the wrong reasons".
  • Base classes have a tendency to become littered with all sorts of unerelated code.
  • It forces you to lock down design, often quite early in the development process. (Premature lock down in a lot of cases)
  • Changing this at a later stage becomes just harder and harder.

So with closures/delegates/function pointers, you normally pass around some function instead of subclassing.

So back to the question:

If your language has closures/delegates/function, do you use template method, and when ?

+3  A: 

When I used Java, yes. But for languages with "closures/delegates/function", Lua in my case, no I don't anymore, instead I've been leaning more and more towards decoration pattern for most of my needs.

Robert Gould
+2  A: 

Yes, I use template method all the time, in the D programming language. Closures, delegates and function pointers are by their nature very loosely coupled to the base class. This is a good thing when you want this loose coupling. On the other hand, sometimes the behaviors you're customizing are by their nature very tightly coupled to the base class. Such behaviors would be useless in just about any other context. In cases where this coupling is necessary, the template method pattern is the cleanest, simplest way to express it.

A simple test is that you should always use strategy/closures/delegates/function pointers if communication between the base class and the customizable behavior is one-way, i.e. the base class calls the customizable behavior and that's it. If the customizable behavior needs a reference to the base class so it can invoke methods, etc., then the template method pattern is often the simplest way to proceed.

dsimcha
It is intriguing to read your answer. Could you give an example for where template method pattern is 'absolutely' the best, particularly where coupling is good?? Just assumed coupling is bad always!
ragu.pattabi
@ragu: The point isn't whether coupling is good or bad. The point is whether it's necessary or unnecessary. If it's necessary then IMHO the easiest way to express it is template method.
dsimcha
@dsimcha: I understand you point for answering the question in hand. My question is generic. To me coupling in template pattern is a bad side effect. Any examples of coupling being good?
ragu.pattabi
@ragu: You're missing the point. I'm saying **if** the policies are going to be tightly coupled to the base class and need to know a lot about it, **then** the template method pattern makes this easy to express. Coupling is never good, but it's sometimes necessary. I'm just saying that if you use strategy or delegates or something when the policies have to know a lot about the base class anyhow and can't be reused in other contexts (are tightly coupled to the base class), you really haven't decoupled anything but you've made your code more verbose and less readable.
dsimcha
@dsimcha: I like your perspective about template method pattern with respect to inevitable coupling. Thank you for the clarification.
ragu.pattabi
A: 

I'll add one more answer while I'm revisiting this thread:

The template method pattern is better than the strategy pattern when the policies you're customizing your base object with need to know about each other and can only make sense in a very limited subset of all possible combinations. For example, let's say your base class has a concrete function doIt(), and hooks beforeDoIt(), designed to allow the policies to initialize themselves and afterDoIt(), designed to allow the policies to clean up after themselves. You wouldn't want to set these behaviors independently because they only make sense when paired.

dsimcha