ComposedMethod and Inheritance
In Smalltalk Best Practice Patterns, Kent Beck describes a pattern called ComposedMethod. The basic idea is that a program should be divided into methods that each perform one identifiable task. Each method should be written so that its operations are all at the same level of abstraction. This is a very good pattern, and well worth using.
It becomes even more important when using inheritance and working in a base class. Consider the following code for drawing line charts (in Smalltalk using the CairoGraphics library):
This is a long, procedural method that doesn’t really communicate what it’s doing. Some of the drawing code has been extracted into other objects (like Axes and Plots), but this is still not a very nice method and mixes up levels of abstraction.
What if we wanted a variant of this Chart class that wants to do something differently, like use a different background color, or draw plots differently? The author of this method has left us with only one option: we have to duplicate this method and then change the parts that need to change, leaving us a future maintenance problem.
Instead, we can refactor the code into a ComposedMethod:
Not only is this version more readable and understandable, it is easier to customize with subclasses. The more pieces we break our methods into, the more “hooks” we provide to subclasses for customizing just the right part of the behavior.
It might even be desirable to break things up a little bit more:
setting the source on a CairoContext
is a different level of
abstraction than telling an object to render itself:
I might not always break things down this much, but this variant does allow easy customization of the various colors by subclasses.
Inheritance is not the first tool I reach for when designing, but when I need it, I try to make it easy for subclasses to do what they need to do. ComposedMethod is one way to do that.
By the way, you really should read Smalltalk Best Practice Patterns, even if you’re not a Smalltalk programmer. It will teach you a lot about good low-level design. You can listen to the Ruby Rogues book club episode about the book if you want more information first.