Friday, August 12, 2005

Template pattern

Last month, i was designing an event handling system for one of our modules. I had two layers, and each layer had an Observable. It was something like


As you see whenever something changes in top, topChanged() will be invoked. The BottomObservable is interested in TopObservable, so it will get that event. (since BottomObservable is a TopObserver).

There will be many BottomObservable implementations. Each of these should trigger a bottomChanged if anything happens, also it might need to restrict one event. For eg, if a topChanged() occurs, BottomObservableImpl1 should fire, BottomObservableImpl2 should not fire etc .. depending on the TopEvent (not shown in diagram).
Since the handler logic (ie iterating through bottomObservers and invoking bottomChanged()) is same for all the BottomObservableImpl's, we can put them in an abstract class and extend it. So now the problem becomes, how to make the decision. Here is where the Template pattern comes. We can make topChanged as the template method(ie one which has the algorithm for invoking observers), and inside it we can call a validate method, which should return true inorder for the invocation of observers. We can make validate a protected method (this method is called hook). Now all the BottomObservableImpl's need only implement the validate method which returns true/false depending on TopEvent.
So in the end, the impl's benefitted code reuse through inheritance, but was still able to control the logic through the hook method.


Interestingly today, Martin Fowler also wrote about this .. here.

One of the thing i did with validate method was making it abstract. Also i made the topChanged() method as final. But Martin Fowler shows an example of JUnit framework, where if one wants to extend the framework and if the runBare method (template method in junit) was final, then you would run into problems. So i decided not making topChanged a final method.
Another thing is i can provide a default implementation of validate which simply returns true.

1 comment:

Zeus said...

Oh I see now...