2010-08-23

The Shu Ha Ri of Inheritance versus Composition

Tauziehen
For ages now, there is an ongoing discussion (to not say war) in the OO communities on wether it makes sense to prefer Composition over Inheritance or not.

My personal impression is that a lot of the heated debate stems from confusing advice given to beginners with what the experts do. A useful mental tool I like to use in occasions like this is the concept of Shu Ha Ri. Here is how I currently think about it:

Shu

You are (relatively) new to object oriented design. Inheritance is rather easy to understand, polymorphism a little bit more abstract. Inheritance is easy to do, composition a lot more work, or so it seems. It's likely that you are overusing inheritance, and that you could benefit from making more use of composition. That's fine, it's the usual learning step you have to take. Once you experienced how inheritance works (and where the problems lie), it's good advice to favor composition over inheritance, so that you can learn what the pros and cons of that approach are.

Ha

You have experienced the perils of overusing inheritance. You have experienced the flexibility that composition brings you - and where investing into composition actually doesn't seem to pay back much. It's time to start experimenting with a balance of inheritance and composition, and to find your own rules of when to use which.

Ri

Thinking in terms of inheritance versus composition doesn't make much sense to you. You know that both are just tools in your quest of producing maintainable, SOLID code. And you can easily refactor code from using inheritance to composition and back on a whim, so why make a fuss about it? Just use whatever your gut tells you makes sense at the moment.

11 comments:

  1. For beginners inheritance doesn't even seem to be that easy to understand, still it is often taught to OO beginners right as the second thing (after methods + attributes). Would be much better if authors+teachers would explain composition thouroughly before introducing inheritance.

    ReplyDelete
  2. Man.. you are great.. First time I met someone online who is thinking in the same lines as me :)

    ReplyDelete
  3. I learned that inheritance is a is-a relationship whereas composition is a is-part-of relationship - two very different things.

    ReplyDelete
  4. @Anonymous - what do you do with a "relationship" and "part of relationship" ?

    ReplyDelete
  5. inheritance isa - a rolls royce is a car
    composition hasa - a rolls royce has 4 wheels, but a wheel is not a car.

    a rolls royce class will be a large composite class that inherits from the abstract car class.

    A rolls royce class is a good example of the similarities and differences of composition and inheritance.

    ReplyDelete
  6. Using UML (Universal Modeling Language) you model relationships with lines between objects.
    The inheritance relationship has an open triangle at the end of the line pointing to the base object.
    The line representing a composition relationship has a filled diamond at the end pointing to the composition object and an arrow at the end pointing to the part object.
    Only a few OO-languages feature composition/aggregation as a first-level primitive - in contrast to inheritance. Therefore the part object must be implemented in some way, e.g. as a simple variable or more often as an array or vector of other objects, the parts. Or, the other way around, the part objects contain references to the composed object.
    - Eduard

    ReplyDelete
  7. @Markus - I wholeheartedly agree. In fact I think the very first thing you should teach is probably polymorphism.

    And once they start teaching inheritance, it's probably a good idea to deemphasize the connection to the "real world". Problem is, it's so tempting, because at first glance it makes so much sense, and therefore the teaching job so much easier (if you don't care much about the resulting designs).

    ReplyDelete
  8. @Anonymous - of course they are different relationships, if they were the same, we wouldn't need two. ;)

    But that doesn't mean that we can't transform a design from using one to using the other. For example, a Customer can be a Person. Or a Customer can have PersonalInfo. Or a Person can have a CustomerRole.

    ReplyDelete
  9. @Eduard - all true, but I'm not sure what it adds to the discussion on how to decide when to choose which?

    ReplyDelete
  10. @Ilja:
    I do not agree with you and think it's not a good idea to deemphasize the connection to the "real world". Because modeling the "real world" is the only way to decide which one to choose.
    Actually it not even a choice. Natural language tells us what kind of relationship we have to deal with.
    The choice comes in when we have to express the relationship by using some programming language and the chosen language does not support one or both types of relationships directly.

    I agree with Marko and would suggest UML as the first language to teach.

    - Eduard

    ReplyDelete
  11. Hi Eduard,

    sorry for the delayed response.

    I can say from my own experience that "modeling the real world" is absolutely *NOT* the only way to decide which one to choose, and my point is that it's also by far not the best one.

    Natural language is way too ambiguous to base a program design decision on it. I'm assuming you are aware of the "a square IS A rectangle" problem.

    In my experience, a good way to go is to *first* decide on the relationship to use, based on the which one creates the best trade-off in terms of simplicity and flexibility, coherence and cohesion. And *then* choose your identifiers, so that they make sense in the light of the relationships.

    That also explains why I don't think that working in UML is sufficient to learn to make those decisions, as only coding the design in a programming language will let you experience the forces that make one design more desirable than the other.

    ReplyDelete

Thank you for your comment!