Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I watched a bunch of lectures on Clojure and functional programming by Rich Hickey as well as some of the SICP lectures, and I am sold on many concepts of functional programming. I incorporated some of them into my C# code at a previous job, and luckily it was easy to write C# code in a more functional style.

At my new job we use Python and multiple inheritance is all the rage. My co-workers are very smart but they have to produce code fast given the nature of the company. I am learning both the tools and the codebase, but the architecture itself slows me down as well. I have not written the existing class hierarchy (neither would I be able to remember everything about it), and so, when I started adding a fairly small feature, I realized that I had to read a lot of code in the process. At the surface the code is neatly organized and split into small functions/methods and not copy-paste-repetitive, but the flip side of being not repetitive is that there is some magic functionality hidden somewhere in the hierarchy chain that magically glues things together and does work on my behalf, but it is very hard to find and follow. I had to fire up a profiler and run it through several examples and plot the execution graph as well as step through a debugger a few times, search the code for some substring and just read pages at the time. I am pretty sure that once I am done, my resulting code will be short and neatly organized, and yet not very readable.

What I write feels declarative, as if I was writing an XML file that drives some other magic engine, except that there is no clear documentation on what the XML should look like and what the engine does except for the existing examples that I can read as well as the source code for the 'engine'.

There has got to be a better way. IMO using composition over inheritance can help quite a bit. That way the computation will be linear rather than jumping all over the hierarchy tree. Whenever the functionality does not quite fit into an inheritance model, it will need to be mangled to fit in, or the entire inheritance hierarchy will need to be refactored/rebalanced, sort of like an unbalanced binary tree needs reshuffling from time to time in order to improve the average seek time.

As I mentioned before, my co-workers are very smart; they just have been doing things a certain way and probably have an ability to hold a lot of unrelated crap in their head at once.

I want to convince them to give composition and functional as opposed to OOP approach a try. To do that, I need to find some very good material. I do not think that a SCIP lecture or one by Rich Hickey will do - I am afraid it will be flagged down as too academic. Then, simple examples of Dog and Frog and AddressBook classes do not really connivence one way or the other - they show how inheritance can be converted to composition but not why it is truly and objectively better.

What I am looking for is some real-world example of code that has been written with a lot of inheritance, then hit a wall and re-written in a different style that uses composition. Perhaps there is a blog or a chapter. I am looking for something that can summarize and illustrate the sort of pain that I am going through.

I already have been throwing the phrase "composition over inheritance" around, but it was not received as enthusiastically as I had hoped. I do not want to be perceived as a new guy who likes to complain and bash existing code while looking for a perfect approach while not contributing fast enough. At the same time, my gut is convinced that inheritance is often the instrument of evil and I want to show a better way in a near future.

Have you stumbled upon any great resources that can help me?

share|improve this question
    
Do your coworkers have code examples as part of their documentation? That would be the shortest distance between point A and point B. –  Robert Harvey Nov 27 '12 at 0:57
    
@Robert Harvey, the specific code at hand deals with scraping various sources for data - some data arrives daily, some weekly, some hourly, some by email, some via ftp, some as an excel sheet, some as an html table ... I have all the code that deals with existing sources and urls and credentials, so given enough time I could figure it all out. My problem is that I feel it is wrong to obsessively look for commonalities between CSV files and excel sheets and html and email attachments to the point where classes that deals with this data have three common parents. IMO sometimes code dupl is ok. –  Job Nov 27 '12 at 1:08
    
Have they ever been bitten by the fragile base class problem? –  Robert Harvey Nov 27 '12 at 3:50
    
If you would like to get answers try moving your question to the top, and then add your experiences to support the question. Also try to be more specific in the question so its clear that a right answer is possible. –  Mathew Foscarini Nov 27 '12 at 3:57
    
Have you seen the Zope Component Architecture yet? It makes composition a snap, adaptation removes the need for most mixin classes. –  Martijn Pieters Nov 27 '12 at 10:24
show 1 more comment

4 Answers

Without seeing a specific example, it's difficult to say if the inheritance is inappropriate or not. Sometimes a problem is inherently complex, and "magic glue" code could just be a sign of good (albeit poorly documented) abstraction.

That being said, if the code truly can be improved by applying a given design principle, the best way to prove it to your coworkers is to do it. Take a small part, change it to use composition instead of inheritance, and present that code. You've already discovered that throwing a phrase around doesn't help. That's because they are comparing concrete and familiar code to your theoretical concept. You have to make your concept just as concrete. Another academic example won't help.

share|improve this answer
add comment

It's not a duality; the question is not "should I use composition or inheritance", but "at which points in my object graph do I want to have inheritance hierarchies".

As far as examples go, I like to come up with car metaphors, so here goes.

Suppose you have an abstract base class Vehicle, and two classes that implement it: Car and Truck. They have a bunch of methods, e.g. get_num_wheels() and get_fuel_type(), get_num_seats(), etc. All is fine, but now you need to further split up the Truck class, because you have to support two-axle trucks (with four wheels) and three-axle trucks (six wheels). You also have to support cars that run on diesel as well as cars that run on gasoline. So now you have TwoAxleTruck, ThreeAxleTruck, DieselCar and GasolineCar. Oh, but now your passenger car comes in a pickup version with just two seats - two more classes, because that car can also be diesel or gasoline powered. And now the customer wants you to track the kind of cargo your vehicles can support; there's eight different classes of cargo, and all types of trucks and pickups should be able to support it. Is anyone counting? And we have another problem: pickups and two-axle trucks have a lot in common, but because the pickup inherits from Car and not from Truck, we have to duplicate that common behavior over both classes.

This is where composition comes in: We define a class Vehicle, which has a few properties, say Seats, Wheels, Engine, CargoHold, and each of these has a polymorphic type. The beauty is that the vehicle itself doesn't have to be polymorphic anymore: you can just combine individual instances of your component base classes to form any kind of vehicle you need. Note that we're still using inheritance to share common functionality: we've just split up the functionality into related groups, and build individual inheritance trees for each of them. Obviously, this works best if the components are functionally orthogonal, that is, that they can function mostly independently - e.g., the wheels don't need to know what kind of cargo they're transporting.

On a side note; Python's OOP model addresses some of the problems found in the classic inheritance situation through mechanisms such as advanced multiple inheritance (unlike, say, C++, python resolves base class conflicts such as the diamond problem in a well-defined and useful way), mix-ins, run-time object construction, etc. Because of this, multiple inheritance can sometimes be the better solution in python even if it would make for messy code in something like Java or C#.

share|improve this answer
    
+1 For last paragraph. The composition over inheritance is a big deal in Java and C# that does not translate as well into Python. –  MrFox Apr 5 '13 at 18:02
add comment

Technically what you are asking is impossible to be obtained; composition and inheritance are two distinct concepts when speaking about object modeling and one cannot be replaced by other.

When modeling there is nothing wrong with inheritance; the real problem is when in reality you do not have inheritance and in code you have inheritance. When you just use inheritance only for the sake of code reuse you usually go wrong; here composition is a better approach. It in this scenario, that the famous GoF principle "Favor composition over inheritance" is applied, that is use inheritance when and only when you model an "is-a" relationship; it would be a pretty bad design idea to model an "is-a" relationship via composition. Also, there are many more "has-a" relationships in the real world than "is-a" relationships.

On the other hand when you are not really modeling a real-world entity (software stuff) in order to obtain code reuse, composition is preferred in most of the cases. There are example that could be given here.

share|improve this answer
1  
AFAIR the GOF book says exactly the opposite: favor composition over inheritance. –  faif Nov 27 '12 at 11:11
    
@faif You are right; that is what I meant but I wrote it wrong. –  m3th0dman Nov 27 '12 at 11:22
    
-1 The GOF quote is "Favor object composition over class inheritance", you say it would be bad to model an "is-a" relationship with composition without saying why, and say that examples could be given without giving any. –  Michael Shaw Nov 27 '12 at 11:24
    
@Michael Shaw The first part is pretty obvious imo; inheritance is more powerful than composition because it permits polymorphism. For the second part look inside a good framework; JCF for example is not so complex. –  m3th0dman Nov 27 '12 at 13:25
    
@m3th0dman: What you originally said was that it would be a bad idea to model an 'is-a' relationship with composition. Saying that inheritance is more powerful than composition doesn't explain that. –  Michael Shaw Nov 28 '12 at 23:10
show 4 more comments

It is not 'Composition over Inheritance' it is 'Composition and Inheritance in accord'

share|improve this answer
2  
without an explanation, this answer may become useless in case if someone else posts an opposite opinion. For example, if someone posts a claim like "It is 'Composition over Inheritance' it is not 'Composition and Inheritance in accord'", how would this answer help reader to pick of two opposing opinions? Consider editing it into a better shape –  gnat Apr 5 '13 at 17:48
    
It was a very, very oblique reference to "The Book of Five Rings" by Miyamoto Musashi. I apologize for presuming a literate audience. –  leed25d Jul 2 '13 at 18:26
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.