“Composition Over Inheritance”, and Why You Should Care

Posted by Stephen Cook

“Composition Over Inheritance” is an important phrase for software development, however it is also a phrase that is often overlooked, or ignored.

In this post, I aim to explain the phrase, and justify why, as a professional developer, it’s something that you really should care about.

 What is “Composition Over Inheritance”? #

Composition is when a class has access to another class instance via its fields. For example, consider the following code:

Here, ClassA is composed of ClassB . We get access to ClassB‘s public members by calling them on the instance of ClassB.

Alternately, we would achieve the same functionality with inheritance using the following:

Here, ClassA inherits the functionality of ClassB. We get access to ClassB‘s public and protected members for free.

“Composition Over Inheritance” simply means to not use inheritance, and instead to use composition.

Note: this does not mean to always pick composition. Inheritance has a perfectly valid use-case, as I explain later in this article. The phrase should instead be taken to mean that — if in doubt — to err on the side of composition.

Why Should I Care? #

Looking at the code samples above, it appears as if inheritance is much faster, easier, and it gets us access to protected as well as public members. So why should we bother to use composition at all?

The short answer is for testing, and for code maintainability. If you think that these aren’t good enough reasons, consider that the following graph of time spent by developers, on average:

(Data taken from “Maintaining Mental Models: A Study of Developer Work Habits“)

You can see that only 36% of time is spent writing new code, on average. For the other 64% of the time, on average, you will be dealing with previously written code. It pays to write code to be maintainable the first time round!

Why Is Composition Better For Testing? #

Consider the hypothetical case where we want to create a JsonGetter class, that takes some URL and returns the JSON object of the file there. If we were to take an inheritance style, we might decide that JsonGetter extends GeneralTextFileGetter, which already gets the file, and turns it into a string for us.

This is fine, but now when we come to test JsonGetter#getJson, how do we go about doing this? Probably the best way is to create a mock JsonGetter object, with a mock getFile method.

Now what if we had lots more methods, such as getJsonSafely and getFileSafely, that only accept HTTPS connections? Or getJsonFtp and getFileFtp that gets over an FTP connection? And worse, what about the likely scenario that we also have an XmlGetter, HtmlGetter, and so on?

Very quickly we begin to have a lot of tedious work ahead of us.

But how could this have been handled differently using composition? Consider the following implementation for JsonGetter

Now ideally we would use a IoC container (such as Spring) to handle JsonGetter‘s dependency on GeneralTextFileGetter (i.e. actually instantiating the getter) — but that needs a whole article to itself. For now let’s just use the setGetter method purely. To test our code we can now create the following getter:

And test our mockJsonGetter. Any of the problems mentioned for testing inheritance mentioned earlier can now be fixed, with reasonable ease, by simply adding to the MockGetter class.

Why Is Composition Better For Maintainability? #

Especially if you’re using protected members, inheritance can lead to a more rigid system, with classes being needlessly interdependent. Consider again the case of our JsonGetter. Imagine that, at some point, our code base is changed, and someone adds a public GeneralTextFileGetter#getBytes method, to return the an array of bytes that constitute the file. Because we’ve inherited from GeneralTextFileGetter, JsonGetter now also exposes this method — but we don’t want it to; it doesn’t belong as a public method for JsonGetter.

So what can we do? Using inheritance, our best option might be to break the GeneralTextFileGetter into 2 different classes. We might decide to create 2 classes like:

We can now have JsonGetter extend GeneralTextFileGetter with no problems.

But what about all of the other classes that extended GeneralTextFileGetter previously? Do these need the getBytes method? We now need to manually change every single subclass of GeneralTextFileGetter to correctly inherit from either GeneralTextFileGetter or GeneralByteFileGetter.

In composition, we would simply not add the method. This is done for free for us; we simply do nothing.

So Should I Always Use Composition? #

No, absolutely not. Inheritance is a useful programming construct. You need only to be careful to not use inheritance in cases where the problems mentioned above might occur. For example, an ArrayList is a perfectly valid subclass of the List class.

A good rule of thumb, when deciding if ClassB should extend ClassA (as mentioned in one of the replies to this StackOverflow), is to ask the following question: “If I were to ask for a ClassA instance, and received a ClassB instance, would I be surprised?”

E.g., if I were to ask for a List object, and received an ArrayList object, I wouldn’t be surprised at all — meaning it’s probably correct to use inheritance.

However if I were to ask for a GeneralTextFileGetter and received a JsonGetter, I would be a little surprised — meaning it’s probably correct to use composition.

Some other related pages around the web that discuss composition over inheritance:

Comments are closed.