The importance of Composition
Many times when we are designing our programs model, first thing most people, including myself, want to start doing is inheriting from other classes. This makes for a nice large hierarchical beast. Not that there is anything wrong with that, but it can lead to certain problems (from my own personal experience, it usually does). With composition, the programmer no longer has to extend from the parent class. You are able to expose only the methods you are interested in. In this article, I really want to discuss the importance of composition. I feel as programmers, many of us find inheritance easier and we often use it without thinking about the repercussions it may bring to us.
I would like to just give a quick example of composition. If you have some sort of base class that your application will be inheriting from, lots of times you just extend it.
public class BaseClass{ public void doStuff(){...} } public class NewBaseClass extends BaseClass{...}
Nothing wrong with that and it is quite common to use. Another way we could do this is:
public class NewBaseClass{ private BaseClass _baseClass; public void setBaseClass(BaseClass baseClass){ _baseClass = baseClass; } public void doStuff(){ _baseClass.doStuff(); } }
Using the typical example of “IS-A” vs “HAS-A”, the first example IS a BaseClass. The second example HAS a BaseClass. From this example, it is difficult to see the advantages that something like this has to offer us. The laziness factor that almost all programmers have kicks in when they see we have to write functions that call the same functions on the BaseClass. While on the outside, it may seem like we are just doing extra work for no reason, there are many advantages that this approach has to offer.
When you use inheritance, you acquire the functionality of your baseclass at compile time. Note that in my short composition example, we have a setter for our BaseClass. This is because with composition, you acquire your functionality at runtime. Once again this might difficult to see the importance. When we assign something at run-time, it gives us the ability to swap out implementations without having to recompile our code. In fact, the decorator pattern, amongst many other design patterns, take advantage of composition by this technique alone. You are able to just write however many BaseClasses you want and swap out the implementation at runtime.
I love the use of interfaces. To me, they are the greatest thing next to sliced bread. However, I cannot think of one instance where I worked on a project where the interface did not change in some form or another. New methods get added, old methods get removed, types change, etc. It is the standard rule of thumb that when using an interface, make sure you have done it right the first time. Once that interface is published and goes to the client, that is it. Once you change that interface, everyone elses code breaks. Now if instead of using inheritance, we took advantage of composition, we would not have to worry about it. The interface can add as many methods as it wants, there is much less of a change that it will break (if they remove the function, then not much you can do about it). With composition, we only expose the methods that we want to use. We no longer have to worry about relying on the parent class or implementing their functions.
When designing out projects, it is very easy to design things while you are thinking a problem through. When you are doing this at the design level, lots of people will just inherit from parents classes. A implements B, C extends B, etc,etc. But what if D needs some functions from C but not from B? Surely you could always just implement what is in C that you dont need and not do anything with it, but that is just poor design. You could create another hierarchal level and go from here, but this is where trouble begins. You now have this extremely large, tightly coupled and difficult design to follow. The alternative approach would be to use composition. Using this, we will have fewer classes to worry about in our design and we will have much more diverse objects. Following this, when we have fewer classes, our hierarchy becomes smaller and more focused, thus easier to follow.
Now this is not to say inheritance is bad and should be avoided. There are many instances required. However, I do feel that it is often abused. Partly because programmers are naturally lazy and its much easier to extends a class rather than expose the methods on a class. The other reason though is (I feel) its a methodology that is often overlooked. With the use of composition in your code, you will be able to produce a much more flex and stable application.
Great explanation. It’s all about the loose coupling in our designs.
Thanks dear,for explaining things in such a nice manner.
it is very very god but you should have to be add more information.
Example would help in a much better way.
very clear… keep it up, thank you
Appreciate it.
It’s nice comparison
Very nice article
wonderful article.. very clean and clear in explanation.. However a simple example would have been (wonder)2