Certainly, the Gang of Four did a lot to popularize the notion.
Yet, there are little places where people still tend to trip and fall back into inheritance as a way of sharing commonalities.
The Template Method pattern is one such place. People almost always implement it this way...
Inheritance-based Template Method pattern |
...but there isn't really a good reason to make the interface for the specialization be a protected part of the generalization. It's just a carryover from habits formed before design patterns thinking was as prevalent as it is, today. It's the coccyx of the software development industry; a vestigial holdover from a time when it served a now-extinct purpose.
There's another way. One with no downsides and an almost unassailable upside. You can use inheritance to categorize and composition to pull specialization into the generalization.
Composition-based Template Method pattern |
Either way, the benefits of the latter design far exceed those of the former design without any meaningful drawbacks. Here are a few of the most prominent benefits of a composition-based Template Method pattern:
- You have multiple categories of specialization, which vary independently.
- It's easier to test each specialization directly.
Again, if your views on design patterns make you think I drew a Strategy pattern, then the same advantages would hold, with different language describing it: You can have multiple "Strategy patterns" that vary independently of one another and each implementation of a "Strategy" is more easily and concisely tested.
I implore people those of you are considering refactoring to a classic, inheritance-based Template Method to ask yourself "What would it really cost me to take this all the way to favoring object-delegation over inheritance?"