Template Method
The problem
The shop exports its daily sales report as CSV for accounting and HTML for the manager’s dashboard. The structure is identical – header, one line per sale, footer with the grand total – only the formatting differs. Two independent report classes would duplicate the iteration and totalling logic, and the copies would inevitably drift (one gets a bug fix, the other doesn’t).
The pattern
The invariant algorithm lives once in an abstract base class as a final method; the variable
steps are protected abstract hooks that each format fills in:
String csv = new CsvSalesReport().generate(sales); // same skeleton,
String html = new HtmlSalesReport().generate(sales); // different steps
Benefits
- The algorithm is written once – iteration order and total calculation cannot drift between formats.
- The sequence is protected –
generateisfinal; a subclass can change how a line looks, never whether the footer comes last. - Adding a format is trivial – implement three small methods; the hard part is inherited.
One caveat so nobody copies these as serializers: the formatters are deliberately minimal. Real CSV needs field quoting (RFC 4180) and real HTML needs escaping – both jobs for a library. The lesson here is the skeleton, not the formats.
A note on modern practice
When the base class would have only one hook, prefer passing a lambda (Strategy) instead of subclassing. Template Method earns its keep when several steps vary together and the skeleton must be enforced – which is why frameworks are full of it.
Seen in the wild
AbstractList/AbstractMap (implement a few methods, inherit the rest), servlet HttpServlet
(doGet/doPost hooks inside a fixed service flow), JUnit’s lifecycle around your @Test
methods, Spring’s AbstractApplicationContext.refresh().
Implementation
SalesReport– the abstract base with thefinalskeleton.CsvSalesReport,HtmlSalesReport– the formats filling in the hooks.