Meh. I think this phrase has been repeated until it has lost any connection with the original intent and turned into a generic "INHERITANCE BAD! COMPOSITION GOOD!" without much meaning attached to either word.
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:
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.
> the basic statement has been dogmatized to the point where you get code like this:
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).
Under the hood, mixing in modules actually is inheritance. An anonymous class is created that has all the module's methods, and this class is added to the inheritance hierarchy.
They are quite literally identical, even if Ruby tries it's best to hide that fact.
While it's possible to overuse inheritance, I don't think replacing it with composition is all that much better, and in addition all those forwarding methods that do nothing more than call another (could they even be optimised out?) are a great example of code that would need to be written, consuming resources like programmer time, but otherwise serves no true useful purpose to the functionality of the software. The complexity only changes form, so instead of tracing the flow through an inheritance hierarchy you're just doing it through chains of forwarding methods. It's for this same reason I don't believe so much his argument for readability and short classes - breaking everything up does not make things simpler, it makes the complexity spread out over a larger area; while it may be true that it is easier to understand an individual piece, it becomes more difficult to understand the system as a whole. This is especially important when debugging, where "can't see the forest for the trees" is a big hindrance.
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."
That's a fair point, although long chains of forwarded methods could be indicative of poor design - writing inheritance via composition in much the same way that one may write Lisp via Java. Granted, it's very easy to say that this is a bad idea, but that's part of the art of good OO design. :-)
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.
> The complexity only changes form, so instead of tracing the flow through an inheritance hierarchy you're just doing it through chains of forwarding methods. It's for this same reason I don't believe so much his argument for readability and short classes - breaking everything up does not make things simpler, it makes the complexity spread out over a larger area; while it may be true that it is easier to understand an individual piece, it becomes more difficult to understand the system as a whole.
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.
While it's a well-written article, it really seems like beating a dead horse. Composition over inheritance is a basic rule of OO programming, so much so that it has its own wikipedia page (http://en.wikipedia.org/wiki/Composition_over_inheritance)
Many of us still learned about OO in school, where inheritance was all but beaten into us, and composition was not mentioned. And based on what I've seen in interviews, this is still a common model taught in school. Composition is in the process of winning as the default method of composing things together in OO (see, for instance, Go), but it has not won yet.
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.
Composition always takes more boilerplate, because inheritance is noting more than composition with a bunch of default choices for a privileged component (single inheritance) or arbitrary sorting of components (multiple inheritance) made so the programmer doesn't have to write them (but also loses control).
Expanding on shanemhansen's point, where in Python subclassing is just a matter of mentioning the superclass in the right place in the class construct but composition requires substantial boilerplate, in Go, composition is just a matter of mentioning the composed element in the struct definition and inheritance requires a lot of manual boilerplate. It isn't technically impossible to implement something that is as much "inheritance" as it is in Perl, or especially as much "inheritance" as it is in Javascript, which I say with full knowledge of the object model in Javascript, but you will have to implement it yourself. (Courtesy of the lack of generics you won't even be able to factor out the boilerplate very well.) Whereas composing two things together is as easy as:
type TwoComposedThings struct {
ThingOne
ThingTwo
}
where ThingOne and ThingTwo are types. If ThingOne and ThingTwo do not have any conflicting method names, you're done. (If they do, you can actually still compile but when you try to use a conflicting name you'll have to manually disambiguate, and some subtleties could arise.)
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.
Do you have examples? Most modern Java libraries I know (e.g. Guava) implement interfaces and heavily use composition.
The "inheritance based" things mostly got deprecated/replaced when Java 1.5 introduced generics and most libraries needed to be heavily changed anyways.
The Android API is fascinatingly anachronistic. I have been programming Java since 1.0.2, but only recently started working with Android. It's been like stepping through a portal back to a time when we had no idea how to structure software.
Sadly, many of the "older" programmers haven't learned any better. And sometimes it's a limitation of the language (eg, Java which doesn't allow default implementations in interfaces).
I haven't really noticed that this particular horse needs much beating (I work mainly in the C# world). It's drilled so well into beginner programmers that they tend to forget other principles like Single Responsibility.
This. There aren't enough dead single reponsability horses :P. This should be drilled in new and experienced programmers over, and over, and over again. And then some more. Because while it sounds so simple it's actually all to easy too violate and because it applies to each and every layer of a project. I'd even say most design patterns are actually proper implementations of SRP in one way or another. Most of the time I have a feeling something if off with my code, it boils down to some pieces just doing too much, hereby dragging others down with it.
Anecdote applied to this particular topic: the intern, proud of having used composition as much as possible, creating mostly classes composed of 10+ other classes and functions that might as well be called NowDoItAll().
> Hierarchies usually start out small. But, when new features are added and scope creeps, they get deeper and more abstract and messier.
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.
But is true that some languages make some kind of bad/problematic code MORE common, and requiere discipline and/or knowledge to combat it (and like in this case, is likely that the avg developer is not aware of the alternatives at all.)
Your wikipedia link actually does a good job of showing why the composition shown in the article is poorly conceived. The whole point of 'composition over inheritance' is that your object is still polymorphic on the composed-of classes.
I agree, but it is a well written article with interesting (simplified) real-life examples, so might be good to show the concept to an unaware or beginner programmer.
And everyone likes to read stuff that reinforces their own belief :)
>While it's a well-written article, it really seems like beating a dead horse
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.
"I was told about inheritance, but had to learn from other coworkers and experience that composition is much favored over inheritance."
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.
You're missing the most important cases - there are cases where it could go both ways in terms of ISA vs. HASA, in which case (the article says) you should use HASA.
Just saying "use the tool appropriate to the job" dismisses the entire problem where in the real world, it isn't clear what that is.
I'm not responding to the article, I'm responding to the parent, who is saying that encapsulation is "much favored" over inheritance. It is not. At least, not amongst more experienced programmers.
Even in marginal cases, you can reasonably decide that a data model should use inheritance. There's no presumptive bias against it.
That's just normal multiple-inheritance. Nothing like mixins.
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.
I don't know if you've ever used Django, but the entire thing is based on inheritance. When they introduced Class Based Views it got so complex that someone had to make this site just for exploring the inheritance tree: http://ccbv.co.uk
Multiple inheritance with your discipline to not do more complicated things. Only inherit from base 'object', nothing else, so you will have no complicated inheritance problems.
Which, in reality, rarely happens. Looking through the code in the Python standard library shows how even the exemplar mixin examples are rarely so pure.
It's not DRY, but then again, the chances of not overwriting, or more likely adding something to that method are pretty small when your project becomes more than an illustration of a principle.
For example, what if you want to add custom animations any time your `Character` takes an action? Suddenly, all that boilerplate you "abstracted" away through mix-ins is back, with a vengeance. How about if your physics for a `Projectile` are different than for a `Pickup`? What if your character suddenly picks up a Sling of Thrown Voices, and needs to apply conversation snippets to its projectiles?
In simple examples, mixins are great and reduce a lot of boilerplate, but in reality they are rarely so clean.
> For example, what if you want to add custom animations any time your `Character` takes an action?
What's wrong with this?
class Character(PhysicsobjectMixin, FightMixin, TalkMixin):
def attack(self):
# custom attack animation here
return super(Character, self).attack()
def defend(self):
# custom defend animation here
return super(Character, self).defend()
For me, it's still clear that 'attack' and 'defend' extends the funcionality of the 'FightMixin'. I can see even the first glance, those are inherited methods, because they use super() (call parent methods)
> How about if your physics for a `Projectile` are different than for a `Pickup`?
You need to implement two classes anyway. I see two possibilities:
I. If you have to implement this kind of different physics behavior only for Projectile. (Maybe you don't even need a mixin.)
II. If you have more Projectile-like objects, but they are not all the same.
class FastMovingPhysicsobjectMixin(object):
def update_physics(self):
pass
def apply_konckback(self, force):
pass
def get_position(self):
pass
class Projectile(FastMovingPhysicsobjectMixin):
pass
class Arrow(FastMovingPhysicsobjectMixin):
pass
> What if your character suddenly picks up a Sling of Thrown Voices, and needs to apply conversation snippets to its projectiles?
Is this a weapon which doesn't shoot projectiles, but make damage with voice or what? :D
Then I think it's totally different, because if Character can have all kinds of different weapons and those behave different ways, mixins don't fit here. I would rather implement that like this:
class Sword(object):
def attack(self):
# swing
def defend(self):
# defend
class SlingOfThrownVoices(object):
def attack(self):
# shout loudly
def defend(self):
# pssszt, be quiet
class Character(PhysicsobjectMixin, TalkMixin):
def __init__(self, weapon):
self.weapon = weapon
def attack(self):
# custom attack animation here
self.weapon.attack()
def defend(self):
# custom defend animation here
self.weapon.defend()
then weapon can be instance of either Sword or SlingOfThrownVoices. Note that Mixins are still in use and no complicated inheritance problem occured even if you have hundreds of weapons.
Consider how these things get stored. In the inheritance model, you might have a big quad tree or some other data structure of PhysicsObjects, and just run through and call updatePhysics() on all of them.
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.
I've seen this problem in projects I've worked on recently. It's gotten me more interested in Ruby mixins as a solution, though I haven't worked on any really complex object structures in Ruby. The project in question is in C#, and you can sorta-almost do something like it by creating interfaces and putting the methods that should be shared as extension methods on it, but it feels very hacky.
I think this is a tooling issue. People initially tend to favor inheritance because it looks cleaner than composition. Mixing a lot of unrelated code in the same class makes things hard to find. (which method applies to which composed object?)
In languages that build in a concept of traits/mixins however, this isn't an issue.
I disagree that mixing remove this issue. Even with mixins, you will still have places where all of that boilerplate from composition comes back, just with a concept like Python's `super` thrown back in.
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.
I don't quite understand this. In my opinion JS "classes", if you want to call them that, look, feel and act very clunky. My opinion, of course... Please could you explain to me how you feel Java "classes" feel clunky and look wrong? I'm genuinely curious, and open to being convinced.
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.
I would prefer this with "why a shallower abstraction pool is better than a deep one." I've seen some compositional concoctions that were just as terrible to deal with as inheritance based ones. I think I've even contributed/originated some.
Ha, that's one of the few things I remember from that book. (Not knocking the book, just my poor memory.) I remember it being a big "a ha!" for a project I was working on.
When I try to choose between the two, I often like to think if the object I try to inherit from is from the same domain/context and solves a related problem.
In the example in the article a PhysicsObject solves the problem of calculating coordinates in space and from the beginning it was not designed as something to be used in the game by itself. While the character participates in the actual game and executes the game logic. The character does not 'inherit' from PhysicsObject, it merely knows that PhysicsObject represents it in the space.
I think one of the biggest reasons why most libraries/frameworks/apps/etc. use inheritance over composition is the easy with which the underlying languages allow the use of inheritance as opposed to composition. Most of these software writers know SOLID and other OO principles but when they're faced with the actual implementation, inheritance is just too damned easy to implement.
The Wikipedia article chton mentions (https://en.wikipedia.org/wiki/Composition_over_inheritance) ends with the following when discussing the drawback of composition (boilerplate for forwarding methods): "This drawback can be avoided by using traits or mixins."
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?
the idea is that you create a mixin that has only the reference to the physics object and the forwarding methods. If you implement that mixin, it will be exactly equivalent as writing them out in your class, but you are spared from having to do it for every single class with a physics object.
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.
Mixins can be implemented in a variety of ways, they don't need to be unmodularly inlined into class/object definitions as in scala. Also, mixin-style inheritance is by definition linearized multiple inheritance (at least according to cook/bracha, things get weirder with the Gabriel/Common Lisp definition).
It's true that they can be implemented in the same way, but the idea remains the same. Seeing mixins as inheritance is a far narrower definition than held by most languages (or libraries) that implement them. Mixins don't put any requirements on the polymorphism of the object that implements them, which ordinary inheritance does.
It's common to use the Flavors/Lisp defintion of mixins, but I'll make sure to read up on the Bracha-Cook paper about them.
There have been many implementations of mixins, and many that I'm aware of, like Scala, are inheritance based. The nice thing about mixin style inheritance is that inheritance becomes much more composable. The type of an object then is not its class, but the set of mixins it extends.
Scala's implementation is definitely an interesting and a valuable one. I'm not debating that inheritance-based mixins are useful, they definitely are. It's just that they aren't necessarily inheritance-based, and there are many implementations of mixins that aren't, so defining it as such is at best somewhat limited and at worst misleading.
On a side note: scala's implementation, internally, is composition-based, since they compile forwarding methods to static methods into the class. They add an interface for those forwarding methods, so it can be used for polymorphism (which is what allows the fun things) but for their system to qualify as mixins, that interface is not necessary. For a very quick reference about this, you can look at http://stackoverflow.com/questions/2557303/how-are-scala-tra...
The type enhancement means that traits could replace classes completely in scala, which is kind of exciting. The problem with traits is that state must be inlined even if implementations are not (so they are a mixture of mixins and small talk style traits). I'm well versed in how they are implemented in scalac.
What non-CL mixins are not inheritance based? Python?
Oh absolutely, the type enhancement is what makes it so interesting to use, but the point is that it's not necessary for it to be a mixin. It's a very nice extra.
I'm not sure about python, but Ruby completely inlines the mixin's code. It needs to do this because instance variables can be created anywhere, including from inside the mixin, but they still need to apply to the object of the actual class. This gives interesting cases for collisions, where 2 mixins create the same instance variable, but it's a decidedly non-inheritance way of doing it.
I use a mixin pattern extensively in C# that involves an interface to say the object provides a mixin object (C# also provides for partial classes, but its not good enough). Polymorphism is preserved via this method (though all clients delegate through MixX). Actually, I don't see private mixins (that don't at least effect the object's v-table) to be very interesting: why not just create and delegate to an object then?
The Brache-Cook has only a simple view on Mixins in CLOS and Flavors. Actually the more interesting parts are not described. Instead they focus on problems they perceive, but which rarely play a role in practice.
In this case I'd argue that the roles are a bit messy and Character has too much knowledge. Character should not know that physics objects can be updated, and certainly shouldn't be calling updatePhysics. You could end up with an updated Character interacting with a Character whose physics state hasn't been updated yet.
applyKnockback: Character -> Physics object -> Physics engine
updatePhysics: Physics engine -> Physics object -> Character new position (x, y)
The burden of proof should fall onto the user of inheritance to justify his decision. Interfaces plug delegates is more tedious to implement, but greatly reduces the chances of an architecture turning into a complete train wreck.
I often wonder why declarative delagating is not a first class concern in programming languages.
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.