So I watched this talk by Sandi Metz dealing with the "Null object pattern", composition, inheritance and general Object Oriented design principles. It was really nice and you can see it here on youtube. The whole talk was great but there was one part that really struck me. I want to emphasize that part in this blog to spread the word. Basically: watch the talk. If you want to know what I liked in particular, come back or stick around :)
In the second part of the video Sandi talks about "the house that Jack built", apparently a british nursery rhyme. She describes classes that output "house"; output it randomly, output it repeating each line, etc. It is a constructed example but it displays problems with inheritance very well. This is not me saying inheritance is useless, mind you. It displays problems with improper use of inheritance.
I'm guessing most of us heard that inheritance is for is-a relationships and composition is for has-a relationships one time or another. The eye-opener in this talk was the definition of is-a. The pitfall that surrounds is-a.
In her talk Sandi works trough an example that has various classes that output House in some way:
- There is just House
- There is a RandomHouse which outputs the lines in a random order
- There is a EchoHouse that outputs each line twice
Up to this point in her example all Houses extend House (except House itself, you follow? :P). Then RandomEchoHouse needs to be created. What do we extend? RandomHouse or EchoHouse? Both cases have us end up with duplicated code from the other. Or RandomEchoHouse extends House as well and code from EchoHouse as well as RandomHouse is duplicated.
But all these houses are a House right? These are is-a relationships, we need inheritance right? Wrong! That is the part I liked best about this talk. There is only one House. That house however has-a(n) Order. It might also have-a Formatter that echoes each line.
So while it seams obvious that RandomHouse and EchoHouse are Houses they are not. Random is not a House, random is an Order. Order (so not random) is not a House, it is an Order. And echoing each line twice certainly not is-a house :)
Is-a is a useful relationship to model inheritance by, but don't get caught by fake relationships.
Really, just go watch the video though: https://www.youtube.com/watch?v=9lv2lBq6x4A
I think we should make the distinction between the concepts in the domain (RandomHouse, EchoHouse) (Domain Model) and the way they are modelled in the system (Data Model).
It is okay for the user of a domain to think in is-a relationships (RandomHouse is-a House). Just because we model it in a compositional manner we need not convince the user that he needs to think differently about the domain.
Let's take the bike. There's ladies' bikes and men's bikes. We might model the fact that the frame is different as an attribute of the bike. The color of the bike is also a feature. And there's much more.
To bike users a white ladies' bike is-a ladies' bike bike and a ladies' bike is, of course, a bike. It is not an abstract bike with a ladies frame and a white color.
That's just the way we choose to model it :)