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?

25 Feb 2012

One hundred and one interfaces and implementations

In recent years there has been a surge of blogs and posts discussing design patterns, anti patterns and, in general, how to design your code well. It is great to see so many passionate developers chatting about how they can be creating code that is decoupled, cohesive and just easy to use. Design patterns make it really easy to jump into someone else's code and immediately know what is going on. It makes it faster and easier to know what is going on under the hood. When you get to a statement like this

public MyBuiltClass doSomething(String name, String address) {
  // some code....
  return myBuiltClassBuilder.build(name, address);
}

you don't have to dig through the the MyBuiltClassBuilder to figure out what is going on. But there is a difference to having read a book like Elements of Reusable Object-Oriented Software and understanding the concepts and applying them in the real world. One design pattern that everyone advocates, is to
Program to an 'interface', not an 'implementation'. GoF
and with this statement we can quickly go down the wrong path. Now, the rules to this can vary as to whether your API is publicly exposed or not but what we need to understand is that you don't need to provide a interface for every class that is created. With today's IDEs it becomes less of a problem because they're smart enough to figure out when you have a single implementation of an interface to just display that implementation, but what you can quickly get yourself into is something like the following,


an interface for every implementation. When this begins to happen in large projects, it can be a nightmare for someone who is onboarding to learn your code and traverse through endless interfaces and implementations (and it gets extremely annoying when the implementation class name is just interface name + "impl" a little more about this later on). When deciding on whether to create an interface for your implementation consider why you are creating the interface... TO PROVIDE ENCAPSULATION. Encapsulation is a way to hide implementation details from the end user. David Parnas was an advocate of modular systems that were highly cohesive and loosely coupled and said:
We have tried to demonstrate [...] it is almost always incorrect to begin the decomposition of a system into modules on the basis of a flowchart. We propose instead that one begins with a list of difficult design decisions or design decisions which are likely to change. Each module is then designed to hide such a decision from the others. David Parnas "On the Criteria To Be Used in Decomposing Systems into Modules"
Based on the information above, it is fair to say a well designed class can provide the same level of encapsulation as an interface. It can hide design decisions and the difficult knowledge required from the end user. So how do we decide whether to create and interface or not? Like any general philosophy, it can be subjective and depend on the scenario but generally consider the points below
  • Are you providing a complex solution to the end user that they really don't need to care about?
  • Do you ever foresee the possibility of making complex changes or having multiple solutions to the same problem?
If you answered yes to both questions then that is probably a good indicator that you require an interface. In the picture posted above, a well designed CRUD class that contains a DAO would most likely provide the level of encapsulation required. An interface for the DAO makes sense if you think that you may at one stage change the storage method from database to disk.

When creating interfaces and implementations remember to name them with something meaningful. Creating an implementation class name by throwing together the interface name with the four letters "impl" at the end does two things.

  1. Shows that the creator probably didn't think about whether or not an interface was needed.
  2. Provides no context of the actual implementation. Going back to what I was saying earlier, having MyObjectDatabaseDAO immediately tells me what is going on and allows the reader to continue without interruption. A class name like MyObjectDAOImpl could mean you are saving it to disk, database, FTP, etc. The point being it isn't helpful.

Obviously there are other reasons to create interfaces, one being to enforce a contract that allows others to provide unique functionality into your own system, but when creating an interface make sure you know why.