11 Mar 2012

Composition versus Inheritance?

Composition versus Inheritance? When designing components and classes, it's a question that always pops up and seems to stir lots of emotions regarding which is the best approach to take. The question is why? Composition and inheritance shouldn't be seen as competing best practices because they have two very different roles to play in design.
Favor 'object composition' over 'class inheritance'. GoF
It's a term heard many times over and it has a very valid point. Unfortunately, it is a single line taken out of a three page summary that is part of a larger section describing design patterns and reusable software. Composition definitely provides greater flexibility and encapsulation. You can change the implementation without affecting your API, however it does result in a slightly more complex system. Inheritance does provide a more simplistic approach to design but exposes your parent API, meaning that your are forever stuck with being a child to that parent. So what happens when you are creating a design that is unlikely to change in the future? Like choosing a language that is best fit for the job, have a look at your problem and choose what solution fits best.

Deciding on whether design using composition or inheritance can be difficult choice, but answering the following questions can sometimes shed some light on the correct path.
  1. Are you creating or extending a piece of functionality or are you trying to describe a structural piece of information?
  2. If it is a structural design, how complex is that design and is it likely to undergo some frequent major changes over the next few years?
What the questions above are really trying to get at is, are you describing something that is unlikely to change or are you defining how something works? For instance, if you were trying to create a model for animals, using inheritance over composition might make more sense. It would be a nightmare to try and describe the below class diagram using composition. The fact that a tiger is a mammal is unlikely to change in any of our lifetimes (unless there is some freak nuclear war that mutates them, fingers crossed it's something cool). The fact that a tiger is a cat and a cat is a mammal is also unlikely to change. With inheritance the below class diagram would be relatively simple to represent as opposed to composition.
What would happen with the above structural design with generics and grouping via parent types if we were to use composition? If you wanted to perform the following:
public List<Tiger> getTigers(List<Mammal> mammals) {
 // some code
}
the composition design would require you to define a tiger in the following way
public class Tiger implements Cat, Mammal, Animal {
 // some code
}
and use object delegation to provide implementations for the interface methods. This is clumsy and inefficient for something that, truly, will not change. Whilst you may think this scenario is too far fetched, then what about describing your POJO classes for your presentation layer? I have recently worked with a web app where the structural design was described using inheritance and it worked really well for what was required. I could not have imagined doing it using composition.

So should we always use inheritance? Of course not. When creating or extending functionality, composition will generally be a better option. A real world example where composition should have been used instead of inheritance? java.util.Properties. I bet this is one example where the JDK developers would be kicking themselves now. java.util.Properties extends java.util.Hashtable. In what world does a Properties file have anything to do with a Hashtable apart from the fact that they are both key value. It made life easier during the development stage however they are forever stuck with being a Hashtable now, even though I am sure they would love to change it to something else. On top of that they have left the Hashtable API exposed, meaning that you can directly modify and add items to the hashtable without going through the Properties API. Properties are traditionally a string based class, however it's possible to add any object to the hashtable meaning that the Properties.getProperty(String key) method is forced to do the following
public String getProperty(String key) {
  Object oval = super.get(key);
  String sval = (oval instanceof String) ? (String)oval : null;
  return ((sval == null) && (defaults != null)) ? defaults.getProperty(key) : sval;
}
That's right, check every item to ensure it is of type string. How ugly. If Properties were designed using composition
public class Properties{
  private Hashtable properties;

  public String getProperty(String key) {
  // some code
  }

  public void setProperty(String key, String value) {
  // some code
  }
}
it would have been so easy to swap out the internals
public class Properties{
  private HashMap properties;

  public String getProperty(String key) {
  // some code
  }

  public void setProperty(String key, String value) {
  // some code
  }
}
and the problem of the "place anything in the Properties implementation" goes away.

So when you are deciding on whether to use composition or inheritance, ask yourself are you creating functionality or describing something?