Rants, rambles, news and notes from another geek

Inherit to Be Reused, Not to Reuse

I’m surprised how often I have to say this to other developers and engineers, but violations of this simple object-oriented mantra seems to be everywhere. Almost every time I look at a class inheritance hierarchy, I find this principle violated.

Why is this use of inheritance bad? First of all, let’s talk about what inheritance is good for:

  • Polymorphism - In OOP, this means that you can treat derived classes as if you had been passed an instance of the parent. This was formalized by Barbara Liskov in her 1988 paper “Data Abstraction and Hierarchy”. Another way to say is is, “Functions that use pointers or references to base classes must be able to use objects of derived classes without knowing it.” [Martin-96]
  • Categorization - The process in which ideas and objects are recognized, differentiated and understood. Categorization implies that objects are grouped into categories, usually for some specific purpose. Ideally, a category illuminates a relationship between the subjects and objects of knowledge.

Let me refer you to the wonderful book, C++ Coding Standards: 101 Rules, Guidelines, and Best Practices by Herb Sutter and Andrei Alexandrescu:

Despite two decades of object-oriented design knowledge, the purpose and practice of public inheritance are still frequently misunderstood, and many uses of inheritance are flawed.

Public inheritance must always model “is-a” (“works-like-a”) according to the Liskov Substitution Principle: All base contracts must be fulfilled, and so all overrides of virtual member functions must require no more and promise no less than their base versions if they are to successfully fulfill the base’s contract. Code using a pointer or reference to a Base must behave correctly even when that pointer or reference actually points to a Derived.

Public inheritance is indeed about reuse, but not the way many programmers seem to think. As already pointed out, the purpose of public inheritance is to implement substitutability. The purpose of public inheritance is not for the derived class to reuse base class code to implement itself in terms of the base class’s code. Such an is-implemented-in-terms-of relationship can be entirely proper, but should be modeled by composition–or, in special cases only, by nonpublic inheritance (see Item 34).

Let me call out one of the more importance sentences in that quote:

The purpose of public inheritance is not for the derived class to reuse base class code to implement itself in terms of the base class’s code.

The inheritance relationship is one of the strongest coupling relationships we can have in OOP. Everyone knows that coupling is bad and cohesion is good, but we still couple like mad via inheritance. We do this for a number of reasons, but one of the big ones is that very few college grads seem to get taught this in school. It makes me wonder how many undergraduate compsci teachers actually get it. Daniel Pietraru wrote a bit about this and how he has used inheritance questions as interview questions.

The other reason I think it is so common is that our languages and tools make it look so easy and so proper. Even Fowler-esque Refactoring has refactorings called “Pull Up Method/Field/etc.” that seem to be all about putting shared code into the base class. There is also the Abstract Test Pattern in TDD which specifically describes using base classes as “a way to reuse test cases”.

Whenever possible, you should look to use composition instead of inheritance in your designs. The problem is that composition is harder to do, even though it results in cleaner more modular designs. Despite that, composition has a number of benefits over inheritance. Again, I’ll let Messrs. Sutter and Alexandrescu tell it (remember that some of the techniques for pointers and such are very C/C++ centric and aren’t relevant here, but the underlying meaning is still true):

Composition has important advantages over inheritance:

  • Greater flexibility without affecting calling code: A private data member is under your control. You can switch from holding it by value to holding by (smart) pointer or Pimpl (see Item 43) without breaking client code; you would only need to change the implementations of the class’s own member functions that use it. If you decide you need different functionality, you can easily change the type of the member or the manner of holding it while keeping the class’s public interface consistent. In contrast, if you begin with a public inheritance relationship, it is likely that clients have already come to depend on the inheritance; you have therefore committed your class to it and cannot easily change your base class decision later on.
  • Greater compile-time insulation, shorter compile times: Holding an object by pointer (preferably a smart pointer), rather than as a direct member or base class, can also allow you to reduce header dependencies because declaring a pointer to an object doesn’t require that object’s full class definition. By contrast, inheritance always requires the full definition of the base class to be visible. A common technique is to aggregate all private members behind a single opaque pointer, called a Pimpl.
  • Less weirdness: Inheriting from a type can cause name lookup to pull in functions and function templates defined in the same namespace as that type. This is very subtle and hard to debug.
  • Wider applicability: Some classes were not designed to be bases in the first place. Most classes, however, can fulfill the role of a member.
  • Great robustness and safety: The tighter coupling of inheritance makes it more difficult to write error-safe code.
  • Less complexity and fragility: Inheritance exposes you to additional complications, such as name hiding and other complications that can arise in the presence of later changes to the base class.

In essence, inheriting for code reuse makes your design brittle. Changes in strange places manifest themselves in even stranger places. If your language doesn’t support multiple inheritance (like C# and Java), then if you use an form of class-based inheritance in your code, you are effectively preventing good Liskov-style inheritance by people who consume your code. Bad bad bad bad.

When you do use inheritance from a base class in your design, look for these gotchas:

  • Protected methods in the base class - This is the stink that is the smell that Herb talks about above.
  • Calling public methods in the base class from the derived class - Slightly less smelly, but still not good.

Honestly, it makes me want to try to eliminate all nonabstract inheritance in my code. In languages with good duck typing, I’d say eliminate inheritance entirely, because in those systems the only good reason to use inheritance is for derived class code reuse. I know this is an over aggressive reaction but I do wonder what our code would look like if we had good composition constructs in the language (we don’t) and if we either went with pure duck typing (ala Ruby) or interface-only inheritance.

Like that’s gonna happen…

Replacing ExpectedException in NUnit 2.4

Jim Newkirk, Brad Wilson and I have been in agreement about the evils of ExpectedException for a long time. When Jim and Brad wrote xUnit.net, in fact, they left it out and opted instead for a new Throws method that lets you be a lot more precise about what and when you are testing the exception.

But NUnit 2.4.x doesn’t have this feature (2.5 will). Fear not! Jim has written a nice little sample of the Throws method for NUnit 2.4.x that provides this same experience in his new post Replacing ExpectedException in NUnit.

If you are using NUnit today, I would really suggest you read the post and consider changing the way you test exceptions in your unit tests.

In Redmond for the Next Week

Time for another trip home to the mother ship for my monthly dose. I’ll be in building 25 all week and staying at my (still unsold) house in Sammamish. Looking forward to some quality face time with my team.

Speeding Up Vista Boot Time

UPDATE Oct-02 2008:
Apparently this is misleading at best, and at worst wrong. Here is what has been explained to me: The setting adjusted in Step 3 below can only LIMIT the number of processors available to Windows. And if the box is unchecked, it will use the default which is ALL of your processors. Makes sense when I think about it. So as long as that box is unchecked, you are using all your procs. As was said to me: “You can easily check this by setting all those things, rebooting the machine and looking at the performance tab in task manager. It will show you how many cores the system sees.” Thanks to everyone who cleared this up!

Found this little gem while looking for something else… thought I’d share it.

When you have a computer with a recent model CPU, chances are it’s a dual-core CPU. Both Intel & AMD have been producing dual core CPU’s for a few years now. By default, Windows Vista will only use a single core during boot-up. You can easily change this from the System Configuration utility:

  1. In Vista’s Start Search type msconfig & hit the [Enter] key on your keyboard
  2. Once System Configuration has started, select the Boot tab and click the Advanced Options button
    image
  3. In the BOOT Advanced Options dialog, check the “Number of processors” check box, and choose 2 (or 4 if you have quad core) for the number of processors.
    image
  4. Click OK twice.

Done and done. :)

What Is Good Tequila?

I’ve been a tequila sipper for years. When I was young I had an incident with whiskey that put me off it, possibly for life, and tequila has nicely filled that gap.

I know the difference between good tequila and bad tequila. Good tequila is 100% blue agave and has a little number on the label that say NOM ####. That number if the distillery registration number. Look for it.

My good friend and fellow tequila sipper Aaron Mikulich sent me this great article today that sums up good tequila better than I ever could:

bbum’s weblog-o-mat ┬╗ What is good tequila?

A choice quote from the beginning:

First, Cuervo Gold is not good tequila. It is actually a really terrible product, quality wise, backed by some brilliant market. Sadly, most of the tequila consumed in the United States is Cuervo Gold or something equally as bad. And by “bad”, I mean bad taste and vicious hangover.

Amen brother!

OneNote Instant Navigator

We use OneNote a LOT at work. Once you get used to it, it is basically an offline Wiki. You can link all over the place easily, store it on a server to share, and work offline. I love it.

But once you get to using it this way, you end up with a whole bunch of notes. It can be hard to find something when you need it.

Enter OneNote Instant Navigator…

OneNote Instant Navigator

Assign a hotkey (I use Win+I) and now you can very quickly get to any note you want. I love it.

UPDATE: Forgot the link: http://i-navigator.hut2.ru/