Posts Tagged ‘Bruce Sutter’

Improper Inheritance

January 5, 2011 Leave a comment

Much like Improper Inheritance (II) can wreck family relationships, rampant II can also destroy a project after large and precious investments in time, money, and people have been committed. Before you know it, BAM! All of a sudden, you’ve noticed that you’re in BBoM city; not knowing how you got there and not knowing how to get the hell out of the indecipherable megalopolis.

Here’s what the “C++ FAQ” writers have to say on the II matter:

Here’s what Stephen Dewhurst says in “C++ Gotchas” number 92:

Use of public inheritance primarily for the purpose of reusing base class implementations in derived classes often results in unnatural, unmaintainable, and, ultimately, more inefficient designs.

Herb Sutter and Andrei Alexandrescu‘s chapter number 34 in “C++ Coding Standards: 101 Rules, Guidelines, and Best Practices” is titled “Prefer composition to inheritance“. Here’s a snippet from them:

Avoid inheritance taxes: Inheritance is the second-tightest coupling relationship in C++, second only to friendship. Inheritance is often overused, even by experienced developers. A sound rule of software engineering is to minimize coupling: If a relationship can be expressed in more than one way, use the weakest relationship that’s practical.

On page 19 in Design Patterns, the GoF state:

“Favoring object composition over class inheritance helps you keep each class encapsulated and focused on one task. Your classes and class hierarchies will remain small and will be less likely to grow into unmanageable monsters.”

Let’s explore this malarial scourge a little closer with a couple of dorky bulldozer00 design and code examples.

The UML class diagram pair below shows two ways of designing a message. It’s obvious that a message is composed of a header and payload (and maybe a trailer), no? Thus, you would think that the “has a” model on the left is a better mapping of a message structure in the (so-called) real world into the OO world than the multi “Is a” model on the right.

I don’t know about you, but I’ve seen many mini and maxi designs like this implemented in code during my long and undistinguished career. I’ve prolly unconsciously, or consciously but guiltily, hatched a few mini messes like this too.

For our second, more concrete example, let’s look at the mixed design and code example below. Since the classes and member functions are so generic, it’s hard to decide which one is “better”, no?

By looking at the test driver below, hopefully the “prefer composition to inheritance” heuristic should become apparent. The inheritance approach breaks encapsulation and exposes a “fatter” interface to client code, which in this case is the main() function. Fatter interfaces are more likely to be unknowingly abused by your code “users” than thinner interfaces – especially when specific call sequencing is required. With the composition approach, you can control how much wider the external interface is – by delegation. In this example, our designer has elected to expose only one of the two additional interface functions provided by the Base class – the ifaceFunc1() function.

Like all heuristics in programming and other technical fields of endeavor, there are always exceptions to the “prefer composition to inheritance” rule. This explains why you’ll see the word “prefer” in virtually all descriptions of heuristics. Even if you don’t see it, try to “think” it. An equivalent heuristic, “prefer acceptance to militancy“, perhaps should also hold true in the world of personal opinions, no?

%d bloggers like this: