6 ms·
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 i
by chton 12y ago
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 http://en.wikipedia.org/wiki/Composition_over_inheritance)
- Torn 12y agoThis horse still needs to be beaten. 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.
- EdwardDiego 12y ago> 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.
- dtech 12y agoDo 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.
- Torn 12y agoI've seen a lot of it in product codebases (both Enterprise and Startup) I've had to work with. I guess it's different when you're maintaining a library - you have more freedom to version up and rewrite things.
- mercurial 12y agoSadly, 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).
- Zigurd 12y agoThe Android View subclasses are an interesting example of a deep inheritance hierarchy in a relatively modern design.
- twic 12y agoThe 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.
- chton 12y agoI 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.
- stinos 12y agoSingle 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().
- tonyedgecombe 12y agoI wish we could move beyond this idea that just because someone uses a particular language their code is going to be poorly written.
- deleted 12y ago[deleted]
- mamcx 12y agoBut 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.)
- mercurial 12y agoBut a language is not just syntax and a compiler, it is an ecosystem. And for good or bad, programmers rely on and are influenced by this ecosystem.
- kyllo 12y agoNot to mention Ruby on Rails, that codebase is a huge mess of inheritance.
- dtech 12y agoI 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 :)
- chton 12y agoThat's true, but there are a huge amount of resources about this particular thing already. It's pissing in the ocean by this point.
- achr2 12y agoYour 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.
- chton 12y agothat's a good point, in the process of trying to use composition the author has made a (very) leaky abstraction.
- jerf 12y agoMany 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.
- judk 12y agoComposition 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).
- jerf 12y agoExpanding 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.)
- 12y ago
- benihana 12y ago>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.
- moonchrome 12y ago>It seems more natural and intuitive to inherit than compose 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".
- judk 12y agoEffective Java is the textbook of junior professional programming. All your new hires shoyld read it.
- timr 12y ago"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.
- edanm 12y agoYou'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.
- kazinator 12y agoIt's not a rule of OO programming; it's a useful guideline for using certain programming languages that purport to be OO.
- deleted 12y ago[deleted]