Thursday, September 13, 2018

Fantastic Inheritance

I love it when people tell me that they like to eliminate redundancy by turning this...


...into this...




There may or may not be benefits but eliminating redundancy is not one of them. Don't believe me? Let's re-examine those diagrams with a little splash of color.



 ...and...



The former design has two associations that point to an object of type A. The alternative design subclasses two classes from a class that points to an object of type A. Both kinds of relationships must be declared, maintained, and attended to whatever extent is required and supported by the language of choice.

Adding a layer of inheritance didn't eliminate a redundancy, it transmuted one.

Again, maybe that's good but let's be honest about what it is. It could be encapsulation. It could improve coupling. It could make things more expressive. It could improve a lot of code qualities. What it can't be is an elimination of a redundancy.

Yet, despite years of experience and reams of evidence, people seem to think that inheritance has some magical property that makes it more suited to reuse of, for instance, a method. It's a shared fantasy for which I have no explanation.

There is only one thing that inheritance allows a class to reuse that they couldn't reuse via composition: clients. Everything else can be shared by composition with zero additional cost over inheritance, and far more maintainability options.

If you find yourself wanting to move some behavior to a base class in order to prevent it from being repeated, do a quick reality check: Is inheritance really the only way to reuse this? Does it really buy me anything over composition? Then act appropriately for the answers it yields.