Departments


Editor's Forum


The Emperor’s New Shoes

When I first learned about object-oriented programming many years ago, I was introduced to the concept of inheritance through one of those all-too-common zoological illustrations: a sparrow is-a bird, a bird is-an animal, and so on. Then, of course, the author gave each of these classes some clever member functions, like Eat, Fly, and Sleep. Even back then I knew such examples were hokey. You would never see anything like a Sparrow object in a real program, unless it was some sort of special-purpose simulation. Even in a simulation, a sparrow’s position in the animal hierarchy would not likely be programmatically significant.

These taxonomies of animals, plants, vehicles, what have you, became almost canonical illustrations of inheritance, and yet they were lame. They were lame because they gave an unrealistic view of how the real world maps to software; thus, they gave no visceral impression of how inheritance could be used to good effect. You might say I am being too picky. After all, thinking up examples is hard. But my point is, sometimes when it is hard to find a realistic example to illustrate a feature, it’s a good clue that the feature isn’t as essential as it’s cracked up to be. And, as we have discovered many years down the road, inheritance is not as essential as it was cracked up to be. Inheritance is important, even indispensable for some things, but today we know that containment is often the preferred solution. I think if we had been more curious about what was wrong with these examples we would have found that out sooner.

Now I have just finished reviewing the millionth article that uses some sort of Employee object as an example. Again the object has some clever member functions like IncreaseSalary or Promote (which leads to an interesting OO problem — how to keep objects from calling themselves). I would say that Employee has now become the canonical example object. And guess what: it’s hokey too.

To see why it’s hokey, imagine you’re writing payroll applications for a big accounting department. First, realize that all this employee data will be stored in a database. If you’re really lucky, it will be an object database; but more likely it will be a plain old relational database, and you’ll have to use some sort of persistence scheme to get Employees in and out of it. You’re going to write dozens of payroll applications, and they’re all going to demand different capabilities of your Employee objects. Are you going to give your Employee class dozens of corresponding member functions? I hope not. Even encapsulating the apparently simple IncreaseSalary operation isn’t very realistic: if you increase an employee’s salary, it will have effects all over the organization. The fact is, in a typical payroll application, all kinds of different entities will need access to employee data. That’s why data needs to be dumb and unencapsulated; it’s why we have relational databases in the first place.

So maybe there’s still something wrong with our understanding of OO. Maybe our mistake is in trying to model a data-oriented problem as an object-oriented one, or maybe encapsulation isn’t all it’s cracked up to be either. I am not suggesting that authors are wrong to use such examples. Good examples are hard to come up with, and writers far better and smarter than I have relied on Employees, Managers, even Wombats to do their bidding. I am suggesting that readers go even further with such examples than their authors intended: if an example seems a bit artificial, ask yourself what makes it so, and how you would illustrate it better. Who knows, you may discover a great new truth and become rich and famous — or you may just annoy the heck out of the author. But whatever else comes of your curiousity, it will make you a better programmer.

Marc Briand
Editor-in-Chief