Composition vs. Inheritance...

[I really should stay out of these discussions... I really should, but I can’t resist.]

The other day I saw an article on Composition over Inheritance (I forget where I saw it). The article did a good job of explaining what "composition" is. This is my simplistic understanding (which means that someone will probably come in and tell me I have it ALL wrong... what else is new?): "composition" means essentially wrapping objects instead of direct inheritance (so instead of inheriting from X you instead have a private instance of X in your class that you use, but you create your own interface possibly something that looks totally different from the "wrapped" class).

I only really have one concern in all this; at least with what I have read (and not necessarily the last article I read on this subject). The advice almost comes across as "thou shalt avoid inheritance (if you can)." The implication is that inheritance is something bad. Now I understand that inheritance can complicate things in a unit testing scenario (be it TDD or POUT).

The problem is that implication that inheritance is bad. I think it might be better to discuss some things I recently did in the DLRScript source code. I recently used composition to build a compatible XMLHttpRequest object in my DLRScript environment (no, it’s in the unreleased bits which will be released as soon as I can test it properly... I was hoping for a JQuery compatibility, but it looks like that ain’t happening this iteration). I wrapped the SilverLight HttpWebRequest object. This let me create a Mozilla/Safari-compatible XmlHttpRequest object that has no extra features other than what those objects contain.

That said I also have some code I have had in place for some time that also works well. This code inherits from the SilverLight HtmlDocument, and creates a document object that is more in line with what we are used to seeing in client script in the browser. I also have a class that wraps HtmlElement to create an object that is also more familiar to JavaScript junkies. I recently added a style property to each of these elements, for instance. My style property simply utilizes the setStyle/getStyle methods (I forget the actual method names) which is already available in the HtmlElement (for instance) to get/set values of individual style properties. In this case having a few dangling methods doesn’t really hurt because I already need 90% of what is already there. I do have to override a few methods since I need to emit DomElements (my inherited form of the HtmlElement) from getElementById instead of an HtmlElement.

My point is this. Think. Think! THINK!!! THINK!! Don’t just blindly follow a rule. Look at your code. Take control of it. Make it do what you want it to do. Make sure that it makes sense. and if someone else is going to be using it, ask someone else if they think what you are doing makes sense. And then DOCUMENT IT!! At least provide an example of how to use it.

Print | posted on Friday, May 02, 2008 12:41 PM

Feedback

# re: Composition vs. Inheritance...

left by Stephen L. McMahon at 5/2/2008 1:49 PM Gravatar
I appreciate your point. I subscribe to numerous blogs including this one and I most likely read the same article that you are referring to. I have to take what I need and leave the rest. I think that the best rule is, "prefer what works best for the given situation over what does not." -- and get a second opinion -- and a third.

# re: Composition vs. Inheritance...

left by Jimmy Bogard at 5/2/2008 5:04 PM Gravatar
Yeah that's bad advice. The real advice is "_Favor_ composition over inheritance". I think that came out of the backlash when OOP was first introduced, where people tried to create enormous taxonomies of objects, trying to classify them as they would the animal kingdom or something.

There was an assumption that you could attain reusability with inheritance, but it just wasn't the case. It's easier to reuse small composable objects, rather than inheriting from something that does part of what you need, but not all and it's a little different in one place.

Robert Martin's book has a great example of composition over inheritance.

# re: Composition vs. Inheritance...

left by Jimmy Bogard at 5/2/2008 5:09 PM Gravatar
And one last thing, I didn't read the original article, but composition is more about a class using objects, rather than exposing them as a wrapper would. Think something like an "OrderProcessor" that _uses_ an "IMailSender" to send emails. OrderProcessor doesn't expose the email sender, it just uses it.

# re: Composition vs. Inheritance...

left by DevPrime at 5/5/2008 1:59 PM Gravatar
First, Jimmy is correct that composition is really more about objects containing references to other objects. However, in the context of the discussion, some people have proposed that Inheritance has bad side-effects and composition should be used to mimic the desired effects of inheritance while avoiding inheritance itself.

Personally, I think it's a completely overblown over-reaction. All OOP constructs are tools, and each has pros and cons, including composition. Rather than a blanket statement about preferring composition over inheritance, it would have been far more useful for the people making this case to give *very specific scenarios* where inheritance has intrinsic problems and should be replaced with composition-delegation, and more importantly why. The original authors did offer some of that, of course, but most of the chatter afterwards has been just the simplistic blanket statement of "use composition instead of inheritance". I'll say it again - All OOP constructs are tools, and while a circular saw can be more dangerous than a file, there are times the file just can't do what the saw can. I just don't like these sorts of generalized statements because they contribute to the lack of critical thought necessary in an engineering environment. You can hardly call that "best practice".

# re: Composition vs. Inheritance...

left by Edward Buatois at 6/24/2008 8:41 AM Gravatar
Having known about this controversy for about ten minutes, and having thought on it, and having started to write three very different responses and thrown them completely away, I think the whole thing is a tempest in a teapot, and based on a fundamental if understandable misunderstanding of what OOP is and what it is for. In a way, OOP is like chess -- easy to understand the rules, years to master.

Put simply, there ARE times to inherit, but there are ALSO times to just call the "superclass" API.

Put more directly, OOP is all about "isa." If you have an object that IS NOT really a special case of a class but nevertheless needs some of the functionality of that class, then by all means, instantiate the class within the object and call the api of the class.

If, on the other hand, your class is a "specific case" of the class, then by all means, subclass (inherit from) the class.

For God's sake, yes, if you're using inheritance to shoehorn in behavior that is not "isa" with the superclass, and which the superclass was never really designed to do, then you do so at your own risk.

Inheritance is not "bad," but it it easily misunderstood.
Title  
Name
Email (never displayed)
Url
Comments   
Please add 5 and 4 and type the answer here: