Martin Fowler wrote about the Call Super smell. This occurs when you are allowed to override a method in a parent class, but you must (as opposed to can) call the parent implementation in your method.
As Martin says, this is a code smell. Why? Because it’s easy to forget, and if you forget it, you get a failure that may be hard to diagnose.
The right thing to do, of course, is to use the Template Method pattern. This allows you to provide “hooks” for subclasses to override. Of course, these hooks can then become smells in their own right if the subclass tree proliferates.
One of the best examples in this is in JUnit… but not in JUnit itself. JUnit uses the Template Method pattern by providing setUp() and tearDown() methods, to be run before and after test execution. Now, there are many extensions to JUnit, and they typically override setUp() and tearDown(). If subclasses want their own setUp() and tearDown() code, they have to… call super! (I remember that StrutsTestCase was particularly bad for this).
This regularly gets mention as a flaw in JUnit. Well, it’s not. Yes, there are better ways to identify setUp and tearDown code, such as the annotation-based approach used in NUnit, TestNG, and the upcoming JUnit 4.0, but there isn’t anything fundamentally wrong with the template method appraoch. The problem was that the extension designers took the easy way out and forced their children to call super instead of taking a bit of time to avoid this (for example, by overriding runBare() to put in pre- and post-test hooks of their own). Martin describes this exact approach in his own entry.
(Another approach that the extension authors could have done is made their functionality available as a Decorator. JUnit has decent decorator support, though constructing decorated tests is mildly annoying)
In short, call super is a problem when using inheritance to provide aggregation. You can avoid this by creating template methods, but in deep inheritance chains (which are their own code smell), these template methods themselves become problems.
8 thoughts on “It’s a bird, it’s a plane… it’s a super call?”
Where the template method is notifying of an event, it is probably better to use the observer pattern instead.
JComponent has addNotify and removeNotify to tell the component that it has been added or removed from something. I often override removeNotify (calling super.removeNotify) to do some cleanup (e.g. removing listeners). It would be much nicer if I could just add some RemovedListener instead.
That’s actually the model being used in the annotation-based schemes mentioned earlier, Neil; the annotations are used to identify observers.
As for the JComponent… I’d recommend writing a Decorator to do this for you, rather than subclassing. I’m not a big Swing developer, so I’m not sure how many decorators you’d need. In generally, this sort of decoration (where there are a lot of methods on the type being decorated) is a good argument for using Dynamic Proxies; unfortunately, they only work with interfaces, not classes…
I can’t explain why, but I can’t stand the word “smell” in a technical or professional context. I don’t know where the use came from, but it seems to be a recent phenomenon.
The term comes from Kent Beck, but it was probably popularised by the reference in Martin Fowler’s Refactoring (Chapter 3: “Bad Smells in Code”).
The connotation is that it’s somewhat disturbing, but you can live with it unless it really stinks.
Recent? Depends on how you define recent. “Refactoring” was out in 1999.
Yeah thats recent in the time frame I had in mind.
The connotation is spot on, but it just sounds a bit, I don’t know, childish (a little bit anyway). There seems to be a whole lot of jargon around like this, which is amusing to the geek in me, but embarrasing when I watch Other People (non geeks) overhear it and snigger/comment.
“Code smell” is a way for consultants like Fowler to criticize your code for tons of money without having to be too specific and also by having an escape hatch. It’s beautifully ambiguous which explains why XP people love to use it all the time.
Actually, can we vote to have this “Code Smell” upgraded to an Anti-Pattern?
I think enough of us have been tricked by it enough times. What else does it take to be an anti-pattern !
Actually, the list of smells in “Refactoring” is highly specific and gives examples of potential problems areas and why they are problems. It’s not ambiguous at all.