Thursday, October 20, 2005

More on Composition versus Inheritance

Is there any more basic OO design decision than this? I started off, like many newer OO programmers, writing code with a lot of concrete inheritance. After some painful lessons and more reading, I now lean heavily toward using composition. So OK. How do we nail down exactly when to use which approach?

Bill Venners writes about this in JavaWorld
. The key criteria to consider is whether the relationship is really an “is-a” relationship, and just how strong the is-a is.

Make sure inheritance models the is-a relationship [...]

An important question to ask yourself when you think you have an is-a relationship is whether that is-a relationship will be constant throughout the lifetime of the application and, with luck, the lifecycle of the code. For example, you might think that an Employee is-a Person, when really Employee represents a role that a Person plays part of the time. What if the person becomes unemployed? What if the person is both an Employee and a Supervisor? Such impermanent is-a relationships should usually be modeled with composition.

He continues to point out that both code-reuse and polymorphism can be achieved with composition, and should not be a reason to use inheritance without a strong is-a relationship. hosts a discussion on the topic. A common approach is to code using interfaces, and use concrete inheritance in the implementations--in other words, use composition (with interfaces) in your design, use inheritance (for re-use or polymorphism) in the implementation. The is-a rule would still apply to the implementations, of course.