Sat 29 Sep 2007
Sorry about the long delay between articles, I was busy getting married. A big thank you to the people who asked if I was going to write any more: I’m back in the game now.
When I built Animator.js, I got some flack for suggesting that inheritance is not a Good Thing. Keen to avoid a holy war I restated my position to ‘inheritance is often useful, but more often overused.’ Over the last few months I’ve been trying to figure out exactly when it should be used, and have concluded - at least for the kind of systems GUI developers build - never. There are better techniques that accomplish the same thing.
In this article I justify my dislike of inheritance as a prelude to my next article introducing an open source animation toolkit that is built without inheritance.
Edit: Eric Herman wrote in with a link to a good article he wrote giving a more detailed example of the same problem from a Java point of view.
Edit 2: OK, I couldn’t make this stuff up. This is a verbatim quote from the Java API documentation for the Properties class that reads configuration from a file:
Because
Propertiesinherits fromHashtable, theputandputAllmethods can be applied to aPropertiesobject. Their use is strongly discouraged as they allow the caller to insert entries whose keys or values are notStrings. ThesetPropertymethod should be used instead. If thestoreorsavemethod is called on a “compromised”Propertiesobject that contains a non-Stringkey or value, the call will fail.
This is what inheritance does to your system! In all fairness, the Java API team introduced the generic collections API to get around this kind of problem, but it’s still funny.
October 1st, 2007 at 1:46 pm
I read the article. Some programming languages support multiple inheritance — a new class can inherit from both bouncing ball and fading ball, for example. Granted this is sort of theoretical, since JS does not support multiple inheritance, but if you were programming in a language that did, would that change your view of inheritance?
October 1st, 2007 at 1:57 pm
Actually JS can support a simple kind of multiple inheritance, since methods can be dynamically copied from one class to another. It’s far from ideal though.
To answer your question, I think that while multiple inheritance eases the pain of inheritance a bit, it still encourages a “one object does everything” style of development.
Conversely, using the Strategy Pattern encourages splitting up the problem into simple well encapsulated components, and is in my opinion a superior solution in every respect except performance.
Take the example in the article: multiple inheritance would have let you create a bouncing fading ball, but it wouldn’t have helped you in splitting the number generation strategy out into a separate class (AbsSineStrategy) behind an interface (NumberSequenceStrategy) that lets you start building up a library of motion strategies that can work for fading, bouncing or anything else that requires a sequence of numbers.
October 1st, 2007 at 5:59 pm
Bernard,
you are fighting the good fight. Too much of what is deemed to be OO code out there is either procedural or naive. See my post on Scriptaculous and the evils of ‘extends’.
http://blogs.pathf.com/agileajax/2007/09/scriptaculous-a.html
October 3rd, 2007 at 7:40 am
This article reminded me about Ruby way of doing things. And if your point is he ultimate truth — then it seems that Ruby the language shares it by making it easier.
module DarkPower
def crushTownsPeople
end
end
class Jedi
def drawSword
end
end
class DarkJedi
(i’m really hopinh your blog won’t screw up the indentation here …)
October 3rd, 2007 at 7:41 am
grr….
class DarkJedi
include DarkPower
end
October 3rd, 2007 at 8:16 am
I think I get the idea - mixins. Mixins are great things, but they are really a kind of multiple inheritance, and hence suffer from the same problems as I mention above.
If you really must have all methods on a single object, Automated Delegation (google for “Automated Delegation is a Viable Alternative to Multiple Inheritance in Class Based Languages”) is the best bet - you can use the Strategy Pattern, but expose the component methods on the wrapping class.
October 3rd, 2007 at 8:38 am
I think what you may want is the ability to pass store and invoke _functions_ rather than objects to express behaviour. In a language with first class functions (such as javascript but not Java) you don’t need the strategy pattern or the template pattern (and so on). I think you’d like is to use a functional programming language such as Haskell, Scheme or ..err.. Javascript.
October 3rd, 2007 at 8:50 am
Good point David. Functions can be used in place of objects and it’s still the strategy pattern. This becomes more convenient with ActionScript or classes written in the MS Atlas framework, since this works:
myAlgorithm.fooStrategy = new QuuxStrategy(3, 4).deliver;
Where deliver() is a method that remains bound to its parent QuuxStrategy object. In this way you get the simplicity of passing in individual functions, and the flexibility of optionally using an object that can be configured.
The reason I don’t do this in ActionScript is that you can’t enforce the type of a function with an interface. In C# you can, through delegates, which bring a whole new level of simplicity to component oriented development.
As for functional languages, I’m waiting for web browsers to support LISP. Perhaps through some GWT-style translation.
October 3rd, 2007 at 9:09 am
Wait no longer…
http://hop.inria.fr/
http://hop.inria.fr/usr/local/share/hop/weblets/home/articles/scheme2js/article.html
(A rather advanced Scheme-to-JavaScript compiler.)
October 3rd, 2007 at 9:14 am
I tried something similar a while back, and string manipulation caused stack overflow errors due to its habit of mapping strings onto recursive linked lists of character nodes. Iterating over the string was done with a recursive function call for each character!
I’ll have a look at this, thanks. What a way for in-house developers to make themselves indispensable: writing UI code in Scheme!
October 3rd, 2007 at 12:57 pm
Glad I found the place to comment. I was reading the article and thought, “how do I contact him?”
I thought the article made good points and was generally sound advice, but I had a couple of questions I wanted to clear up.
1) In the Jedi example, inheritance is still being used. You are simply aggregating dark powers within DarkJedi rather than putting them straight in. I think that’s fine, but was wondering if/how that contradicts what you were trying to show.
2) I also was going to mention mixins or multiple inheritance, but since Evgeny and gs already did so, I’ll just ask about your response.
In particular, you said:
“multiple inheritance would have let you create a bouncing fading ball, but it wouldn’t have helped you in splitting the number generation strategy out into a separate class.”
Of course, I agree here. But, I wanted to point out that it wouldn’t prevent you from doing so either. In fact, while you might be able to say bouncing is something all balls do (and include it in the ball class), I wouldn’t say fading is something all balls do. So having a FadingBall derive from Ball which then used the absSine strategy would make for a clearer object model in this case.
Finally, you also mentioned you “think that while multiple inheritance eases the pain of inheritance a bit, it still encourages a ‘one object does everything’ style of development.”
Do we really care if one /object/ does everything? Now, I definitely agree that one class should not do everything, but from the objects’ perspective, which is that of the running program, I wouldn’t think it matters.
If an object calls theDarkJedi.crushTownsPeople(), it doesn’t care whether the code for crushTownsPeople() is included within DarkJedi or if DarkJedi simply uses another object for it.
In other words, writing code in components is supposed to be for our benefit, not the program’s. Multiple inheritance / mixins seem to achieve that goal.
It could be that I misunderstood what you were getting at with that comment, so feel free to rip into me. =) (ok, maybe not /rip/).
October 3rd, 2007 at 1:47 pm
All good points, I’ll address them one by one:
1) Yes my contrived Jedi example contains an extends statement, so technically uses inheritance, but the important thing is that DarkJedi is now just a convenience constructor that wraps a Jedi and a DarkPowers. If you want to use inheritance to make convenience constructors, that’s fine, it’s putting the implementing code in the extending class that I object to, and that’s what 99% of people do when they extend a class. There are many other ways of combining Jedi and DarkPowers without extending Jedi.
2) I gave Ball explicit yMotionStrategy and alphaStrategy properties to make the example clearer. In a real system you could have something more generic. For example, you could make a PropertyChangeStrategy class that holds a number of strategies and applies them to its containing object each frame:
ball.strategies.addStrategy(”y”, new AbsSineStrategy(80, 200));
ball.strategies.addStrategy(”alpha”, new AbsSineStrategy(0, 1));
Now you can add the ability to make strategies that affect any property of any class by adding one line of code:
public var strategies = new PropertyChangeStrategy(this);
How cool is that?
3) I guess you’re playing devil’s advocate here, but let’s have some fun anyway:o)
MI still ‘bakes’ the behaviour into a class at compile time, and makes one big object with potential to have unforeseen interactions between the multiple base classes. It’s not that I don’t want an object with all those methods, its that I like to see functionality separated by object boundaries.
I don’t deny that MI can achieve everything that the Strategy Pattern can (except runtime modification). However, the way to solve the tangled mess that inheritance leaves us with is not to make a super inheritance system that gives you more rope to hang yourself with.
Problems with MI are well documented. Google for “multiple inheritance problems”. Consider that both Sun and Microsoft decided not to include MI in their virtual machines, meaning that no language that runs on that machine can support MI. C# gives you delegates, which really help the strategy pattern. I think that the language designers are moving away from MI as a way of enabling component driven development, now that people don’t care so much about the real benefit of MI - reducing the number of objects you instantiate and destroy.
October 3rd, 2007 at 8:30 pm
At OOAD level, inheritance represents “is-a”, as you said, at OOP you can implement it by delegation and interfaces. Inheritance in OOP is just an easier way to do it :-).
And your last Jedi code example makes perfect sense, if you read the code, you clearly see:
a DarkJedi is-a Jedi which has-a DarkPower
If you suppress inheritance, you’ll have:
a DarkJedi has-a Jedi and has-a DarkPower
mmm… a DarkJedi has a Jedi inside?? wierd :-)
Ok, let’s model it differently so it makes more sense, let’s have JediPower too:
a DarkJedi has-a JediPower and has-a DarkPower
Looks a little better, but is harder to model the fact that maybe someone has JediPower but is not a Jedi…
There always alternatives and depends on what do you want to represent. The bottom line is with inheritance the pass from OOAD to OOP is more straightforward that without it (assuming you want to use OOAD, of course ;-) )
October 4th, 2007 at 9:09 am
That’s the problem with whimsical examples: since they are not doing real work in a real system, you can’t argue over exactly how to implement them, since the different implementations aren’t producing any results to compare. That’ll change next month when I come back with a real product.
As for inheritance making OOAD easier, that’s only true because people learn OOAD as an exercise in mapping real world concepts onto an inheritance-based architecture. When you have been using the hammer of inheritance long enough, the world starts to look remarkably like the nail of hierarchical classification. Teach people to map the concepts onto interacting components, and I believe that they will learn to find the Strategy Pattern more intuitive than inheritance.
October 4th, 2007 at 7:54 pm
But the example makes sense.
Is the same as a CorporateCustomer is-a Customer or a Customer has-a CorporateInfo ?
There’s no right or wrong, always depends on the point of view of your application.
Probably the best explanation I can come is: if for your domain, the is-a relationship is invariant, better model it with inheritance otherwise use delegation. This forces you to provide a stronger justification when using inheritance (X is-a Y should be true *ALWAYS*).
In my understanding, OOAD is about mapping concepts into interacting objects, not hierarchies.
I agree that people get overenthusiastic about it and overuse is always bad (see what happening to patterns) and leads to this kind of backlash, but inheritance is useful :-)
October 5th, 2007 at 9:13 am
Firstly, good example; my argument is that Customer has-a CorporateRelationship is better.
Here is one example of a real world problem that would be caused by forcing customer classification into inheritance: what happens when customer Dave Foo takes on a corporate relationship while the application is running? You already have an instance of Customer representing Dave live in the application. You need to restart the application to reload Dave as a CorporateCustomer.
This is fine if you’re writing an HTML application in PHP, since the whole application restarts every request. It’s not so good if you’re writing an AJAX front end and a Java back end that both persist for a whole session.
Secondly, the Strategy Pattern is just fine for invariant relationships.
* It helps you write modular code that can be re-used in other places in your application (in the article, AbsSineStrategy was re-used for both kinds of ball, and could be used for wholly non ball related purposes elsewhere).
* It maps better onto relational databases; much of the pain of object relational mapping is overcoming an impedance mismatch between relational schema and inheritance hierarchies that simply doesn’t exist if you use a component oriented architecture.
* It makes it easier to write extremely generic code, such as the PropertyChangeStrategy in my example above. When the strategy is hidden behind an interface, you can write meta-strategies that wrap several other strategies, modifying or combining behaviour. Even if they are invariant, it still helps you compose behaviour.
One can always come up with an example that looks like it would be better modelled with inheritance. My experience is that these examples are very rare in the kind of systems web developers build.
October 5th, 2007 at 9:23 am
Mmm I agree that Inheritance is often used in a bad way.
Still there is a big difference between an “is-a” and a “has-a” relationship.
The is-a relationship let you use polimorphism…
At the beginning of your post, you say that you use Strategy Pattern INSTEAD OF Inheritance… But the Strategy Pattern IS Inheritance.
The fact that java uses the keyword “implements” instead of “extends”, just because it doesn’t support multiple Inheritance does not change the fact that strategy pattern describes a “is-a” relationship.
What you discovered here is just that the “is-a” relationship can’t solve all problems…
Well thanks, but we already knew it :)
October 5th, 2007 at 9:53 am
> But the Strategy Pattern IS Inheritance
No it’s not! Firstly, implementing an interface may count as inheritance in type theory, but “Concrete Class-based Inheritance is evil and must be destroyed” didn’t sound so catchy :o)
Secondly, in duck-typed languages there is either no such thing as interfaces or they are optional, and the Strategy Pattern works fine in them. Clearly interfaces are not required for this pattern, and are incidental to the point I’m trying to make.
> The is-a relationship let you use polymorphism
No, polymorphism lets you use inheritance. Without polymorphism you would not be able to use a CorporateCustomer in place of a Customer, so inheritance would be useless. With the Strategy pattern you don’t need polymorphism, because there is only one Customer class, and that class may or may not have a CorporateRelationship.
> Well thanks, but we already knew it :)
“We”? You must be speaking on behalf of the exclusive club of web developers who bothered to read up on why design patterns matter and don’t just carry on hacking together systems using the first technique they were taught in college and shrugging off the resulting difficulties with an “oh well, software is hard” rather than re-appraising the way they do things. Can I join? I’ve been looking for you for ages!
October 5th, 2007 at 10:55 am
Ahh now I understand.
I think I misunderstood what you mean exactly by Inheritance.
>Secondly, in duck-typed languages there >is either no such thing as interfaces >or they are optional, and the Strategy >Pattern works fine in them.
>Clearly interfaces are not required for >this pattern, and are incidental to the >point I’m trying to make.
Ok, this is clear now
>With the Strategy pattern you don’t >need polymorphism, because there is >only one Customer class, and that class >may or may not have a >CorporateRelationship.
This is not clear. Assuming that for Stretegy Pattern you intend this: http://en.wikipedia.org/wiki/Strategy_pattern
then the “execute” method is a virtual method. You have a pointer to a Strategy object and when you call “execute”, you are calling ConcreteStrategyA::execute OR ConcreteStrategyB::execute, depending of the type of the object your point is pointing at. And this is polymorfism as far as i know…
October 5th, 2007 at 11:35 am
I misunderstood, I was thinking of polymorphism as the ability to pass an instance of any subtype of class C to code expecting an instance of C. Since in type theory, implementing an interface creates a class that is a subtype of that interface, the strategy pattern does indeed use polymorphism.
But, it replaces class-based polymorphism (CorporateCustomer can be used in place of Customer) with interface-based polymorphism (Customer has-a IRelationship, which might be a CorporateRelationship or a different kind of relationship). This is a good thing.
Also, you could implement the Strategy Pattern without an interface. Customer could have a corporateRelationship property which is either null, or contains a CorporateRelationship object.
Is that still the Strategy Pattern? Maybe I’ve used Strategy Pattern and component oriented architecture so interchangeably that I’ve forgotten the difference :o)
October 11th, 2007 at 6:45 pm
I believe it’s for the reasons you outline in the article that a popular concept in OO design is to “favor composition over inheritance”–it makes systems more extensible and easier to maintain down the road.
October 11th, 2007 at 7:24 pm
The title to my article is a slightly more strongly worded version of that phrase, in the hope that more people listen :o)
October 11th, 2007 at 7:38 pm
Hey Bernie, Excellent article, always good to see web developers with an interest in OOAD.
I think my only comment would be that instead of citing the Strategy Pattern as the key to your discussion you should state you’re talking about composition versus inheritance.
I tend to think of the strategy pattern as a way to provide different “algorithms” for a particular task. For instance the classic: providing sorting a collection with a different sorting strategy. It’s not something I’d think of for adding new completely functionality to a class to differentiate it from a super class.
For instance, the in the Jedi example; I’d suggest all Jedis have powers, but the strategy provided for the powers class differs. DarkStrategy vs. LightStrategy.
It does sound like, in that particular example at least, you’re really describing composition. Which would be how you would enhance a particular class in new ways, essentially enabling polymorphism in many situations without the resorting to inheritance.
A good reference for this would be Bill Vener’s article on the subject.
http://www.artima.com/designtechniques/compoinh.html
I may be wrong though, I just see Strategy used a lot, and usually with good reason as it’s one of the most useful patterns.
Thanks again.
October 11th, 2007 at 7:49 pm
Yeah, I do tend to use the term Strategy Pattern when I really mean composition.
October 11th, 2007 at 8:49 pm
[…] The same will be true for OO. In a recent article, a new kid on the block states: Inheritance is evil and must be destroyed. Ignore the pretty flowers and butterflies on his blog… this is war and this guy is a warrior. Or he is just using the ‘let me shout heresy’ technique to get readers. Either way I read his talk. […]
October 12th, 2007 at 3:40 am
Nice article. It points out the problems with inheritance very well.
I don’t agree with the notion of inheritance being evil and having to be destroyed, though. Like in your examples, your ball classes are extending MovieClip - a perfectly good reason to use inheritance. Well, considering all this, the title is probably just slightly exaggerated to gain more attention, which is good.
Personally I find inheritance useful for creating base classes which perform certain tasks. One could argue, that you should use interfaces for this. If it’s something which almost always does the same task but in a slightly different way, I think it’s better to create a basic implementation and then extend the class, overriding some methods to perform the task in a different fashion. Use an interface, and you would have to write all the source code again.
When you mentioned in the comments that the Customer class should have a CorporateRelationship, it made me think of databases: If you’re designing a database for customers, you wouldn’t chuck the relationship data in the customer table. In code, you might have the customer data loaded and then have the relationship loaded for the customers and added as a sub-object for each customer. If you had a CorporateCustomer class, you could in theory put the data for the relationship in the customer table, but it wouldn’t be very good practice in my opinion.
Perhaps this kind of a view will help someone to look at their classes in a different way.
October 12th, 2007 at 7:45 am
I won’t disagree that inheritance is often the simplest way of implementing something. That’s the downfall of articles like mine - you aim to demonstrate a technique that helps manage complexity, and in order to stay under 20 lines the examples you use don’t require that technique.
However, in real systems, I find class-based inheritance bites me in the ass even when I thought it wouldn’t.
> Personally I find inheritance useful for creating base
> classes which perform certain tasks
Sometimes the simplest way to allow users to extend your system is to provide a class with many methods, each of which provides a default action, and allow users to selectively override them. I grudgingly allow this advantage :o) It’s still the wrong way to do it, for the reasons outlined in the article, but when ease of use for programmers of varying skill is the main concern, the benefits beat the downsides.
> If you’re designing a database for customers, you
> wouldn’t chuck the relationship data in the customer table
Of course not, you would have a CUSTOMER table, then a RELATIONSHIP table, and either a customer_id on RELATIONSHIP or a CUSTOMER_RELATIONSHIP link table. Spitting Customer and Relationship into two different classes makes this mapping intuitive: one class per table. Extending Customer with CorporateCustomer means that you have to join the two tables together and put the data into a single object. This makes it very difficult to refactor to change the cardinality (one-to-on-, one-to-many etc) of the table relationship.
October 12th, 2007 at 6:03 pm
> Spitting Customer and Relationship into two different classes makes this mapping intuitive: one class per table
>Extending Customer with CorporateCustomer means that you have to join the two tables together and put the data into a single object.
Which is why looking at the problem from this point of view can be helpful for figuring out a better approach than inheritance.
October 17th, 2007 at 12:47 am
“These classes obviously can’t extend Jedi, so you have to duplicate townspeople crushing functionality across your whole DarkArmy or split it out into utility functions that you call from every crushTownspeople method. Either way, it gets complicated.”
How created further in the article the DarkPowers class is different form a utility class?
October 17th, 2007 at 8:05 am
Arte: If calling code expects the crushTownspeople() method to exist on the DarkJedi object itself, then even after moving it to a utility method you still need a stub method like so:
public function crushTownspeople():void {
DarkUtils.crushTownspeople(this);
}
If calling code expects it to be in a darkPowers property, you don’t have this extra boilerplate code, just:
public var darkPowers = new DarkPowers(this);
Sure there’s not much difference with just one method, but if there are 10 dark methods it becomes a pain in the ass to write and maintain the stubs. Also, if you add another dark method, the first version forces you to update every dark class, whereas i the second version the extra method is acquired by every class with a darkPowers property.
October 29th, 2007 at 3:08 pm
You should take a look at Fragment Oriented Programming (short FOP). With FOP you simply compose your classes from fragments.
The animated Ball examples could look like this
The Fragments for Ball could be StaticColor, StaticPosition and DrawBall
The Fragments for BouncingBall could be StaticColor, Bouncing and DrawBall
The Fragments for FadingBall could be FadingColor, StaticPosition and DrawBall
and if you want to compose a FadingBouncingBall or even a TextureFadingBouncingBall you simply use different Fragments.
There is an implementation of FOP available for C++: http://fragments.wiki.sourceforge.net/
October 29th, 2007 at 6:04 pm
That sounds like a very clever solution to a very real problem, except for the fact that I will never program in C++
They can pry the dynamic languages from my cold, dead fingers :o)
February 14th, 2008 at 9:58 am
Hi there,
Heads on! I’ve been suspecting something like this, but not been able to formalize it. Thank you!
Qi4J, http://www.qi4j.org/ formalizes this thought in the Java world, well worth a look!
February 20th, 2008 at 12:53 am
Hey Bernie,
I think you are right in many regards and you are defiantly on the right track, however I feel your example is slightly off.
If you consider the Liskov Substitution Principle (LSP) and the Open Closed Principle (OCP) you will see that the CrushTownPeople() method violates them.
If we consider what happens with different kinds of Jedi interact with towns people; Good Jedi would HelpTownsPeople(), and if you had a grey jedi it would BeIndifferentToTownsPeople()
So the code that had jedi’s interacting with towns people would not be very polymorphic and would need to know about all the different kinds of jedi.
For more on the subject i suggest reading:
http://www.objectmentor.com/resources/articles/lsp.pdf
Hope this helps.
February 20th, 2008 at 9:36 am
Was the comment intended as a note on the Star Wars universe or the principles of Object Oriented Analysis and Design?
If the former, then quite so: good Jedi would no doubt help townspeople.
If the latter then the LSP becomes irrelevant when you design a system without inheritance. The LSP is concerned with how you model a system of many related objects using inheritance. I am concerned with how you model a system of many related objects without using inheritance!
The whole point of using composition over inheritance is that you don’t substitute one object for one of its subclasses, you always pass in that object and its behaviour will depend on its composition.
If we were to model GoodJedis and GreyJedis (do they exist?) then we would have a public property townsPeopleReaction, which would contain an instance of CrushReaction, IgnoreReaction or ProtectReaction.
Either way, a plain Jedi object is passed to the townspeople, and not a subclass. Liskov be damned.
March 12th, 2008 at 4:10 am
your code examples are well formated and clear enough to convince me! ;D
March 12th, 2008 at 6:49 am
Sounds like you might find Scala traits interesting:
http://www.scala-lang.org/intro/traits.html
You can add them to instances too:
val q1 = new StandardQueue with LockingQueue with LoggingQueue
where LockingQueue and LoggingQueue are Traits (example from the scala book).
Just a thought.