by exch on 7/6/14, 11:36 AM with 90 comments
by al2o3cr on 7/6/14, 5:11 PM
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.
by userbinator on 7/6/14, 2:06 PM
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."
by chton on 7/6/14, 12:46 PM
by kissgyorgy on 7/6/14, 1:43 PM
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.by millstone on 7/6/14, 8:19 PM
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.
by jiaweihli on 7/6/14, 12:54 PM
In languages that build in a concept of traits/mixins however, this isn't an issue.
by taeric on 7/6/14, 6:33 PM
by zak_mc_kracken on 7/6/14, 3:59 PM
"Favor object composition over class inheritance"
[1] http://www.amazon.com/Design-Patterns-Elements-Reusable-Obje...
by pllbnk on 7/6/14, 3:23 PM
by teamhappy on 7/6/14, 1:53 PM
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
by kilemensi on 7/6/14, 3:36 PM
by andybak on 7/6/14, 12:58 PM
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?
by kstenerud on 7/6/14, 2:56 PM
applyKnockback: Character -> Physics object -> Physics engine
updatePhysics: Physics engine -> Physics object -> Character new position (x, y)
updateCharacter: Character reacts to change
by yayitswei on 7/6/14, 2:10 PM
by javinpaul on 7/6/14, 3:12 PM
by _pmf_ on 7/6/14, 2:32 PM
I often wonder why declarative delagating is not a first class concern in programming languages.
by yeureka on 7/6/14, 9:54 PM
by known on 7/6/14, 4:03 PM
by fithisux on 7/6/14, 2:35 PM