I haven't found the original source, but I've always presumed the statement originally referred to some of the bizarro "inheritance-as-composition" stuff in the early C++ days: for instance, you might have a class 'Window' and a class 'Button', then combine them with multiple inheritance to get a 'WindowWithButton', then inherit from that and a 'Scrollbar' class to get 'WindowWithButtonAndScrollbar'.
I can't imagine anybody thinking of that as a "good" pattern today, but remember it was the '90s. :)
Nowadays, the basic statement has been dogmatized to the point where you get code like this:
https://github.com/elm-city-craftworks/broken_record/blob/ma...
This code re-implements Ruby's built-in method lookup algorithm, but with per-instance objects and none of the optimizations available to the real thing. It basically remakes inheritance, slowly and poorly, using composition.
The other one that makes me scratch my head: people who rail against inheritance, then suggest mixins as an alternative. At least in Ruby, the two are equivalent. Check the `ancestors` property on a class with mixins sometime if you don't believe me.
TL;DR (too late) - use your damn brain to make decisions, not just parrot slogans.
From the readme of that repo: "It is not suitable for any real purpose ... it may be a fun starting point for palying around with design strategies ... [the compositional design] is probably a bad idea for a number of reasons, but is worth investigating."
When someone explains at length that some code they've put up on github is experimental, probably-a-bad-idea, not-for-serious-use, just-playing-around-with-design-strategies code, deep-linking to it in order to hold it up as an example of 'bad things people are doing nowadays' seems a little uncharitable.
It certainly makes me think twice about putting my own just-for-fun code experiments up on github in the future (without a disclaimer at the top of every file, anyway).
They are quite literally identical, even if Ruby tries it's best to hide that fact.
I think his example of flexibility is the strongest argument for composition, because in that case the forwarding methods are not a waste - they would need to do (useful) work to determine which of the multiple composited objects they would need to work with.
Being mostly a C programmer who does OO-things, I use inheritance when it's obvious that most of the "methods" will be passthroughs to the "superclass", and composition when there is something more that needs to be done. Also, as I am not constrained by the OO model/conventions of the language, it's more flexible in that I can do things like "inherit" multiple times and even change that at runtime, so there is really no strict separation between composition and inheritance; to me, it's just "which function do I set this to point to."
I ran into this at work recently when refactoring an inheritance hierarchy. My initial instincts led me towards many forwarding calls, but after taking some time to reflect on the problem further, I found that many were no longer needed given the smaller scope of each class.
Preach it! Whilst immense monolithic classes are bad, smashing a system up into a million tiny bits is just as much of a barrier to understanding. It is baffling to me that this is not immediately obvious to everyone.
See also the microservices movement!
And on the topic of Go, note how most common OO languages in use still have more convenient support for inheritance than composition, where "inheritance" is one token in the right place but "composition" takes a lot more boilerplate because there's no support built in, or you have to add a third-party library to make the boilerplate go away. Again, changing over time, but languages change slowly.
Messy inheritance still plagues product Java, C#, and, with the increasing proliferation of MVC frameworks, JS these days.
Hierarchies usually start out small. But, when new features are added and scope creeps, they get deeper and more abstract and messier.
Substitutability (i.e. the L in SOLID principles) does require more boiler-plate when using composition though. Interfaces and mixins (if available in your language) go some way to helping.
The "inheritance based" things mostly got deprecated/replaced when Java 1.5 introduced generics and most libraries needed to be heavily changed anyways.
We have real issues with some complex class hierarchies that another team likes - they keep adding yet another abstract subclass of an abstract subclass to handle more cases, so you can end up following logic up and down multiple levels of classes when reading code, and missing one overridden statement can dramatically change the outcome.
And everyone likes to read stuff that reinforces their own belief :)
I graduated college about 10 years ago, and I was never taught anything near composition over inheritance. I was told about inheritance, but had to learn from other coworkers and experience that composition is much favored over inheritance. Now I mentor a number of junior developers and they need to be told composition over inheritance often. This isn't a problem that has fixed itself, and it's most certainly not beating a dead horse when it needs to be repeated for so many young programmers.
This isn't just a problem with formal CS courses - code schools like Hacker School and Flatiron School have this issue as well. It seems more natural and intuitive to inherit than compose. So this horse needs to continue being being as it's very much alive.
You weren't taught that, because it isn't true. Inheritance is appropriate sometimes, composition at other times.
In particular, when a two objects are modeled by an ISA relationship, you should use inheritance. When they're modeled by HASA, you should use composition.
A Dog is not an Animal that includes Barkable and PeeOnHydrantable, and a SpaceShuttle is not a descendant of Airplane.
Especially when you finally figure out inheritance and OO you fall in to that "when all you have is a hammer".
Composition is not an obvious way to approach this problem when you've been taught to solve problems with inheritance - and it fits "so nicely".
class PhysicsobjectMixin(object):
def update_physics(self):
pass
def apply_konckback(self, force):
pass
def get_position(self):
pass
class FightMixin(object):
def attack(self):
pass
def defend(self):
pass
class TalkMixin(object):
def say_something(self):
pass
class Character(PhysicsobjectMixin, FightMixin, TalkMixin):
pass
class Pickup(PhysicsobjectMixin):
pass
class Projectile(PhysicsobjectMixin):
pass
it's still inheritance, but the classes will be flat; every class only inherits one deep, so there will be no diamond problems and no repeating code.Mixins would be if the classes actually contribute pieces which combine in an interesting way. Like a border-mixin added to a button class would add to the drawing and to the geometry of the object.
from abc import ABCMeta
class PhysicsobjectMixin(ABCMeta):
@abstractmethod
def update_physics(self):
pass
@abstractmethod
def apply_konckback(self, force):
pass
@abstractmethod
def get_position(self):
pass
class FightMixin(ABCMeta):
@abstractmethod
def attack(self):
pass
@abstractmethod
def defend(self):
pass
class TalkMixin(ABCMeta):
@abstractmethod
def say_something(self):
pass
class Character(PhysicsobjectMixin, FightMixin, TalkMixin):
def update_physics(self):
pass
def apply_konckback(self, force):
pass
def get_position(self):
pass
def attack(self):
pass
def defend(self):
pass
def say_something(self):
pass
class Pickup(PhysicsobjectMixin):
def update_physics(self):
pass
def apply_konckback(self, force):
pass
def get_position(self):
pass
class Projectile(PhysicsobjectMixin):
def update_physics(self):
pass
def apply_konckback(self, force):
pass
def get_position(self):
pass
This is not DRY at all. I like mixins much better.In the composition model, we now have multiple classes (Character, Pickup, Projectile), each with an unrelated updatePhysics(). This means code duplication to call the relevant method on each separate class.
We could relate them all via an interface, instead of inheritance; now we can store IEntity or whatever. We will soon discover three needs that are awkward to address:
1. Whenever we want to add some new method (say `fall`), we must go back and implement it separately in each class.
2. Different classes will want to share implementations. For example, both Characters and Pickups bounce on fall.
3. Some classes will want to specialize an implementation to do more. Characters bounce on fall, but also take damage.
In practice you may end up with both: an interface that your engine talks to, but also a common base class that provides sane defaults.
So while interfaces allow uniform interactions with disparate classes, inheritance provides that and also the ability to share and specialize the implementations. So inheritance solves some problems that interfaces cannot.
See also default methods in Java, which makes an interface more like a class, and implementing an interface more like inheritance. The documentation even says that a class that implements an interface inherits its default methods.
In languages that build in a concept of traits/mixins however, this isn't an issue.
And mixins in the wild are rarely so pure as people like to think they are - they often inherit from their own parents or other mix-ins, creating the diamond (or worse!) inheritance problem outlined in the article.
In JS it's rather easy to compose objects. In Java it feels clunky, you code looks kinda wrong when you done.
Note I substituted your usage of "objects" with classes, because they're vastly different concepts. I know, murky water when it comes to JS, but still.
"Favor object composition over class inheritance"
[1] http://www.amazon.com/Design-Patterns-Elements-Reusable-Obje...
Game development seems to be the poster child for composition over inheritance.
Here's a lengthy article that explains it way better (IMHO): http://gameprogrammingpatterns.com/component.html
Now this is where things get a little blurry for me.
Mixins can help with the main drawback of Composition - but Mixins ARE inheritance - so isn't this a contradiction?
If I use PhysicsObjectMixin in my CharacterComposition class then I have to inherit from it. So aren't we back with the perils of inheritance?
Remember that a mixin, by definition, isn't the same as inheritance. The methods, fields and properties are compiled into the class, not inherited. It's essentially a fancy way to 'include' a code file.
applyKnockback: Character -> Physics object -> Physics engine
updatePhysics: Physics engine -> Physics object -> Character new position (x, y)
updateCharacter: Character reacts to change
I often wonder why declarative delagating is not a first class concern in programming languages.