In Design Patterns, the Gang of Four describe the Template Method pattern. In this pattern, a base class method describes the structure of an algorithm or process and calls other methods for the steps. The base class can either force subclasses to implement the step methods or it can contain a default implementation that subclasses can choose to override if necessary.
Consider a very simple unit testing framework. We might create
TestCase subclasses with the name of the test method to
Some subclasses might need to do some setup before running the test,
or teardown afterwards. That’s easy enough to accomplish using
This works, but is less than ideal. Every subclass that needs setup
or teardown now has to override
run and remember to call
Subclasses that only need setup will have a different variant of
run than subclasses that only need teardown. If we decide that we
want to do extra work in
run, then every subclass needs to be
examined to make sure it still works with the new base class
teardown should be called even if the test itself fails
or raises an exception. Given the design above, we’d have to go
through every subclass that implements
teardown and change the
Instead, we can refactor
TestCase to use the Template Method
With this version of
TestCase, subclasses no longer have to override
run. Instead, they just implement whichever of
teardown they need. That’s less code to write, less duplication,
and more flexibility for the base class.
run method from
By using the Template Method pattern, Minitest has been able to add
more features in its
run method without forcing all subclasses to be
changed to accommodate the new features:
- It handles the
INFOsignal to print out information about which test is currently running.
- It times each test so that it can provide timing information about the tests being run.
- It captures exceptions in a uniform way and turns them into test failures.
- It adds more hook methods to the test lifecycle (
The Template Method pattern works really well in concert with the Composed Method pattern. Template Methods should generally be written as Composed Methods.
If you are working on a base class and you find that many of your subclasses are going to have to override the same method and call super, consider refactoring to the Template Method pattern instead.