Sunday, January 13, 2008 #

Oh no! it's a Template method.....

One of the patterns I used to use a lot was the Template-pattern. Wikipedia has a nice article on the template pattern here if you want a quick refresher on what I'm talking about. This weekend I've been digging through some code I wrote about a year ago where I used this pattern a lot and I found it hard to read and hard to test.

The template method is a method that lives in an abstract base-class that calls a couple of abstract functions to do what it has to do. Those functions are then implemented differently in the children of the base-class to make a couple of classes that do the same thing differently. I've got a simplified example where I use it to read tabular data from comma delimited (csv), position delimited (pdv) and xml files.

 image

The first problem was testability. The subclasses contained some private functions that I wanted to test. I could make them public to test them but then client code would be able to mess with the implementation of reading the file. The whole reason for using the template method was to abstract this away from the calling code.

The second problem was readability. Actually I found two problems here.

The first problem is that when you look at code using a CsvReader this pattern makes it harder to find out what it's doing. You expect this class to handle Csv-reading but it only handles simple subtasks, the pattern obscures the higher level logic by putting it out of sight in a base-class.

My code got even messier because I had some code I could reuse between the CsvReader and the PdvReader. These two worked with simple textfiles. But not the XmlTableReader. It made no sense to push this code up to the base-class because of the XmlTableReader. I could put it in an external class or I could add a layer in the inheritance tree above the CsvReader and PdvReader.

image

This looks like a neat solution. But in practice this makes the code even less readable. I've seen template method implementations with as much as 4 levels of inheritance that were completely unreadable.

So how do we make this better? I'll give you a hint. It involves dependency injection and the Strategy pattern. More on this in my next post.

posted @ Sunday, January 13, 2008 1:58 PM | Feedback (0)

Copyright © Mendelt Siebenga

Design by Bartosz Brzezinski

Design by Phil Haack Based On A Design By Bartosz Brzezinski