Michael Feathers called out the anti-pattern of frameworks that require extension of classes in the framework. Hooray!
Thank you for saying this out loud! Frameworks based on class extension are extremely appealing at first, particularly to the control freaks who want tight coupling in their applications (unbelievably I work with quite a few of those). Over time the loss of design flexibility and moving control from the “application” or the “problem domain” over to the framework leads to a lot of stale code that is hard to test and extend. In particular, I’ve seen systems with useful business logic that can’t be reused because it’s locked into framework hierarchies.
This is one of those anti-patterns that once you see it, it’s hard to unsee it.
Essentially, when you’re doing class design, object hierarchies should follow the problem domain. So in an accounting model, you should have classes like “Account”, “Creditor”, “Ledger” and whatnot. When building an application, you end up modelling the application space, which is not as clean, but hard to get away from. So you end up modelling artifacts like “…Handler”, “…Request”, “…Response”, “…Manager”.
A lot of engineers I work with see the problem domain as dumb data objects you pass to Handler or Manager classes, rather than modelling them as functional classes directly. But oh well.
What the superclass anti-pattern calls out is that the framework is taking control of the modelling effort and forcing application artifacts into its own hierarchy. That really moves the modelling effort away from the problem domain and locks it into the framework’s domain. A lot of engineers don’t see why that’s bad, because they just want the framework to tell them what to do. But the system as a whole pays the price for it.
That’s why the surge of POJO-oriented technologies have become so popular. It’s the recognition that I should be able to take my class, as-in, in my own problem domain and hand it to a framework for handling. There’s growing recognition of the power that provides.