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.
I’ve been working on a Flash port of Animator.js that’s been pumped up on performance enhancing drugs and given a flame thrower. It’s a fairly complex software component with around 30 classes, but it uses the Strategy Pattern instead of inheritance. I’ve grown fairly passionate about my anti-inheritance stand, and want to take some time to explain myself. In this article I rant for a few paragraphs in an attempt to persuade you not to use inheritance, and then show you how to use for Strategy Pattern for your own software.
The code samples for this article are in Actionscript but the concept applies just as much to JavaScript, or indeed any object oriented language.
Why inheritance sucks
Skip this and go straight to the code, if you like
All of the pain caused by inheritance can be traced back to the fact that inheritance forces ‘is-a’ rather than ‘has-a’ relationships. If class R2Unit extends Droid, then a R2Unit is-a Droid. If class Jedi contains an instance variable of type Lightsabre, then a Jedi has-a Lightsabre.
The difference between is-a and has-a relationships is well known and a fundamental part of OOAD, but what is less well known is that almost every is-a relationship would be better off re-articulated as a has-a relationship.
Eh?
Instead of extending a class and adding some functionality in the subclass, try putting the new functionality into its own class. Suppose you want to create a DarkJedi class; a dark Jedi is like a standard Jedi, but with dark powers too. The obvious way to do this is by extending the Jedi class and adding some appropriate methods:
// bad class Jedi { function drawSabre():Sabre { ... } } class DarkJedi extends Jedi { function crushTownspeople():void { ... } } dj:DarkJedi = new DarkJedi(); dj.crushTownspeople(); |
This looks like the simplest approach, and it is at first. However, your dark powers are locked up inside the DarkJedi class. If you need to make a DarkDroid and a DarkSpaceship that can both also crush townspeople, you’re in trouble. 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.
Now suppose you had done it like this:
// good class Jedi { function drawSabre():Sabre { ... } } class DarkPowers { function crushTownspeople():void { ... } } class DarkJedi extends Jedi { // DarkJedi has-a DarkPowers public var darkPowers:DarkPowers = new DarkPowers(); } dj:DarkJedi = new DarkJedi(); dj.darkPowers.crushTownspeople(); |
Everything that was possible in the first version is still possible in the second, but because DarkPowers is a separate class, there’s no limit on what kind of object can be evil:
class DarkHippo { public var darkPowers:DarkPowers = new DarkPowers(); public function capsizeCanoe(canoe:Canoe):void { … } } |
Yeah, but I don’t make Jedis. Or hippos.
Good point, but the problem above happens everywhere that inheritance does. I’ll give an example from the Flash player API because I consider Actionscript 3.0 is one of the most beautiful works of software engineering I have used in recent years, and if the team that made it can’t get inheritance to behave properly, how can the rest of us be expected to?
Here are 2 examples of use of inheritance, one appropriate and one not, and by ‘appropriate’ I mean that the problems that inheritance inevitably ends up causing are probably outweighed by the lower complexity.
GoodIn Flash the DisplayObject hierarchy is a set of classes that represent the different kinds of on-screen object: The DisplayObject hierarchy is a good use of inheritance. MovieClip extends Sprite and adds a timeline. A MovieClip is-a Sprite through and through: the fundamental defining purpose of a MovieClip is to be ‘a new kind of Sprite’. A MovieClip can always be used in place of a Sprite, it has the same methods and the same capabilities as a sprite, it is drawn on-screen like a Sprite; it just adds some extra timeline functionality on top. More importantly, you generally don’t need to use the timeline features in the MovieClip class independently of the on-screen drawing features of the Sprite class. It’s not all perfect. Last week I wanted to add some common functionality to both MovieClips and Sprites, but I couldn’t because it’s not possible to modify the DisplayObjectContainer base class that both these classes extend (and I refuse to monkey patch). In the end I had to use MovieClips where Sprites would do, which is inefficient. It would be possible to re-articulate this relationship as has-a: the functionality in the MovieClip class would be split into a Timeline class, and MovieClip would extend Sprite with a public ‘timeline’ property.
// old style:
mc.goToAndPlay("shizzle");
// would become:
mc.timeline.goToAndPlay("shizzle");
But the existing version works well enough, and I think that the Flash API architect(s) made the right decision. |
BadIn flash, code to dispatch DOM events is contained in the EventDispatcher class. EventDispatcher is a bad use of inheritance because in order to dispatch events, classes extend EventDispatcher. This is an incorrect analysis: just because a class can dispatch events, it does mean that fundamental defining purpose of the class is to be ‘a new kind of EventDispatcher’. Chances are that the class has a different fundamental purpose and the ability to dispatch events is secondary to the main purpose of the object. This is fine for DisplayObjects, because all DisplayObjects dispatch events, and DisplayObject extends EventDispatcher, but what do you do if you want to dispatch events from an object that cannot extend EventDispatcher because it is already extending something else, perhaps Array for example? In this case, you must jump through hoops with the IEventDispatcher interface and a lot of extra boilerplate code. This problem would not occur if instead of extending EventDispatcher in order to dispatch events, a class had a public property ‘events’ that contained an EventDispatcher. Instead of calling foo.addEventListener(), you would call foo.events.addListener(). This could either be a convention, or could be enforced with an interface. Now any class can participate in the event system just by adding a public property, because the relationship has been re-articulated from ‘x is an EventDispatcher’ to ‘x has an event dispatcher’. (In all fairness to the Flash player API team, they made this decision because they were following the DOM Events specification, which requires that methods like addEventListener exist on the DOM nodes themselves, not as a separate events object) |
Enough already, show me the code!
An example
Suppose you have a Ball class that implements a red Ball. You extend this class to make a BouncingBall class that, well, bounces. You again extend Ball to make a FadingBall class that fades in and out. Don’t ask me why, let’s just assume your client is strange. It might look something like this (the ball, not the client):
class Ball extends MovieClip { function Ball() { graphics.beginFill(0xAA0000); graphics.drawCircle(0, 0, 20); graphics.endFill(); } } class BouncingBall extends Ball { private var frame:int = 0; function BouncingBall() { addEventListener(Event.ENTER_FRAME, setPosition); } private function setPosition(e:Event):void { frame++; this.y = 280 - Math.abs(Math.cos(frame / 15) * 200); } } class FadingBall extends Ball { private var frame:int = 0; function FadingBall() { addEventListener(Event.ENTER_FRAME, setAlpha); } private function setAlpha(e:Event):void { frame++; this.alpha = Math.abs(Math.cos(frame / 15)); } } |
Now suppose you want to make a ball that bounces and fades. Feck. Your problem here is that bouncing and fading balls aren’t really new kinds of ball, they’re new ways that the same ball behaves. The ball has-a bouncing behavior. Using inheritance, the code that handles bouncing and fading is locked up in the BouncingBall and FadingBall classes and can’t be used elsewhere.
If you’re paying any attention you know the solution by now:
// To create a bouncing and fading ball: // var d = new StrategyBall(); // d.yMotionStrategy = new AbsSineStrategy(80, 200); // d.alphaStrategy = new AbsSineStrategy(0, 1); class StrategyBall extends MovieClip { public var yMotionStrategy:NumberSequenceStrategy; public var alphaStrategy:NumberSequenceStrategy; function StrategyBall() { graphics.beginFill(0xAA0000); graphics.drawCircle(0, 0, 20); graphics.endFill(); addEventListener(Event.ENTER_FRAME, handleEnterFrame); } private function handleEnterFrame(e:Event):void { if (yMotionStrategy != null) { y = yMotionStrategy.nextValue(); } if (alphaStrategy != null) { alpha = alphaStrategy.nextValue(); } } } interface NumberSequenceStrategy { function nextValue():Number; } // Note how one class is used for both the fading and bouncing behavior - componentisation allows // for greater code reuse class AbsSineStrategy implements NumberSequenceStrategy { private var frame:int = 0; private var from:Number; private var to:Number; public function AbsSineStrategy(from:Number, to:Number) { this.from = from; this.to = to; } public function nextValue():Number { frame++; return to + Math.abs(Math.sin(frame / 15)) * (from - to); } } |
Apart from being able to make a bouncing, fading ball, there are 2 huge benefits of this solution:
- You can change the behaviour of each ball at runtime: a bouncing ball can become a fading ball at any time.
- You can reuse number generation algorithms between properties – note how there is only one number generation algorithm – AbsSineStrategy – is parametrised with the too and from values so that it can be use to control alpha or height.
That’s enough theory – in my next Article I’ll actually do something useful with all this stuff!
Download the code for this article
Recommended article
A fascinating and detailed account of the move from concrete inheritance to composition in game programming.

The problem isn’t with inheritance, its the lack of multiple inheritance (C++ is awesome btw) in all of the new languages that only allow single inheritance, which I wish I knew why this decision is being made with new languages. Interfaces seem like a very flimsy piece of tape to get around this issue. Interfaces aren’t even nessisary when multiple inheritance is present.
Multiple inheritance is problematic – google “diamond problem”.
google “forest of trees pattern” or “capability classes and queries pattern”….there are solutions for the dreaded diamond
C++ is NOT awesome. I’m sure most C++ programmers with a clue would prefer to be coding C but were forced into OO compliance by some buzzword-loving management a55holes. Linux Torvalds is a seriously talented programmer and publicly loathes C++, as do countless others.
Not only is classical inheritance a f*cking stupid idea but to make things worse, the way C++ implements it is by far the worst of the bunch.
You are a cargo cultist of the worst kind.
In all fairness, I think that the *worst* kind of cargo cultist would be one that killed kittens or something. Or parked on double yellow lines.
(Gasp!) or maybe killed kittens while parked on double yellow lines.
Scott Meyers is a seriously talented programmer and publicly loves C++, as do countless others…
I’m not convinced. Seems to me inheritance is a tool. Like any other tool, if you use it incorrectly it cause problems.
However, your article will cause me to reflect on my uses of inheritance.
@Jason: You’re right of course, but the Internet seems to prefer bombastic one-sided proclamations to nuanced accounts of pros and cons ;o)
This all makes sense except all your examples still use inheritance. Kind of a let down after the hyperbolic title. :-)
Pingback: Herança x Composição | JornalJava
Pingback: Programação Orientada a Objetos: uma introdução « Rodrigo Silva e problemas…
Pingback: Herança x Composição : JornalJava
Inheritance is God when it is used correctly is wonderful, otherwise is only a mistake.
For example. The truth is your example of inheritance is an example of the use of interfaces. Your example is the same thing to sell guns to American people. They could bought but they don’t know used.
So sorry You’re wrong!
I honestly can’t leave any reply that would improve on the perfection of that comment. It has made my day.
Bernie :o)
unfortunately, programmers ain’t gods
pulling my hair ATM not because I’m using inheritance inappropriately (I do understand what “is-a” relationship means), but because requirements and object responsibilities have changed over time.
inheritance would be awesome if I could time travel and figure out requirements perfectly.
I think that the problem lies with us trying to create largest possible classes while we should be designing smallest possible class. For example in C, I would put two functionalities in a function only if I am sure that I would never use them separately. Rather than keeping two functionalities separate only when I know of their usages separately.
That is how we tackle future needs, because the problem is independent of inheritance.
Excellent post! I completely agree with you. Inheritance is the wrong tool for code-reuse. Unfortunately, in mainstream languages, there’s no better tool, so it gets really really abused. Take a look at traits, you’ll like them…
I rate if used wrong you won’t be able to reuse. However in alot of instances especially in PHP and C++ i find it extremely time saving for larger projects to use inheritance. But as mentioned here it depends what the super class function is.
For instance, say I’m implementing a pluginable cart checkout process. You have different types of Payment Gateways. Each payment gateway has a CheckOutURL(), a Description(), a Title() etc etc. That’s for the PHP side of things.
In c++ the best usage could be thought of in a game. Both NPC’s and Players are renderable, can be controlled (by keyboard or AI module), have a position, orientation, and animation states. To reimplement these for all different types of NPC’s and Players is just code bloat and highly unoptimal.
In the example of this page the DarkJedi example is the perfect example how NOT to use inheritance. DarkJedi is a jedi who is also dark inclined. Therefore I would say Jedi extends both Jedi and DarkEntity (DarkEntity being an abstract for entity that has dark inclinations) .. Therefore a DarkHippo is a DarkEntity and a DarkJedi is a dark entity. In which case both DarkHippo and DarkJedi’s crushTownsPeople(), but only Jedi’s can use the force to do so. The only time this would make sense to use would be if suddenly a normal Jedi wanted to kill off all DarkEntities regardless whether its a Jedi or a Hippo. etc etc.
It obviously depends on your ability to use the language feature to long term advantage which is why inheritance heirachies should not be created at whim but rather planned out in advance using spider diagrams or inheritance trees. Stipulating exactly what a class does thats so much like its parent, and whether the class is infact the parent. Just because the class has the same functions doesn’t mean it is the same thing. Just because you can drive a Boat doesn’t make it a Car, but they are both Vehicles. You won’t take a boat to a car Mechanic so don’t send Vehicles to mechanics, etc etc
Oh, another thing, also take a look at the DCI architecture…
Pingback: A herança é má e deve ser destruída | Dalaz
Good article. It’s always helpful and interesting when someone share experience about those kind of development aspects. I don’t think inheritance is the problem because these choices are related to design. This is why GOF has imagine pattern like Strategy, Command, Observer and others.
But developer needs to determine which one to use : That is answering correctly to Do I need an “is-a” or an “has-a” like “is-composed-of” etc…etc… ?
Multiple inheritance like in C++ may be useful but is not a good idea because it can lead to an ugly or more complicated design than it should be (e.g : When overriding methods…)
But you’re right inheritance is often overused without relfexions…may be there’s some kind of human automatic reflex there :)
In your example clearly Darkness belongs in another class.
Theoretically you could use multiple inheritance for this (if your language supports it). But then you have the diamond problem.
The diamond problem comes from function overriding. Although inheritance is meant to implement “is a” relationship in fact this is not strictly true.
Classes may be related set theory. A class is a set. When we say Dog Inherits Animal, we mean the Dog set is a subset of the Animal set.
Now say we have a rule “all dogs chase cats”.
dog.See(cat) implies dog.Chase(cat)
This could be written as a method,
void Dog.See(Cat cat)
{
Chase(cat);
}
Now suppose we have a class CatLovingDog that inherits from Dog.
void CatLovingDog.See(Cat cat)
{
Greet(cat);
}
This is an exception to the rule that “all dogs chase cats”. So function overrides are a weird cludge exception mechanism, which doesn’t even work for multiple inheritance (the diamond problem). A correct logical interpretation would be that when you call See(cat) on a CatLovingDog you get both implementations.
The diamond problem has lead people to adopt single inheritance, which makes as much sense as saying an object may only belong to one set.
There is another problem in that the return type is not part of the signature in most languages. This is evil because you can’t change the return type on an inherited method.
To summarize, most programming languages do not correctly implement set theory, and are very sick. This is why you are against inheritance. I have seen nothing in your arguments to show that a correctly implemented multiple inheritance system would have any problems at all.
The goal is always single purpose small classes.
IT IS NOT A BALL IT IS A CIRCLE! (new Sprite ().graphics.drawCircle())
Calling it a FadingBall is a mistake like saying YourMotherInClothes extends YourMother.
I have one shape class that can be anything from Circle to Rectangle by encapsulating a style object.
Consider using a Tweener for your animation.
What a funny topic to draw such strong emotion…
You touched something, that I’d call religious believing.
Once I wrote on StackOverflow, that inheritance isn’t all OOP is about, I got several down votes.
Brad Cox (co-creator of Objective-C) was interviewed for the book “Masterminds in Programming”. He was asked, why Objective-C doesn’t have multiple inheritance.
Answer: “[…] If I revisited that decision today, I might even go so far as to remove single inheritance as well. Inheritance just isn’t all that important. Encapsulation is OOP’s lasting contribution.” (Masterminds of Programming: Conversations with the Creators of Major Programming Languages, p. 259)
One thing, you will always hear about sub-classing is, that you are dealing with black-boxes — that you would deal with objects you don’t have to know about how they look internally. But that is just not true: It is white boxing, as the subclass knows the internals of the superclass — and the author of the subclass needs to know these internals too, otherwise he will most likely have unexpected behavior if he accidentally overwrites members of the superclass.
Real black boxing can be achieved by object composition.
@Bernie
If you really want to make your case, I think you should take a classic is-a relationship, like your R2Unit > Droid example, and rearticulate that into a has-a relationship. How is it logical or useful to say that an R2Unit “has a” Droid?
The has-a relationship makes sense because the Droid class does not represent a noun, it represents characteristics and behaviors. Therefore the R2unit “has” Droid characteristics and behaviors.
It’s those characteristics that make it a droid, not because we say it is, but because it looks and acts like one.
Somewhere inside that article is a good and valid point about when it is and isn’t appropriate to extend. But by starting your article with “bombastic one-sided proclamations,” you immediately hurt your credibility. You’ll appeal to the zealots who agree with your one-sided proclamation, but you won’t gain any respect from the good programmers who understand the nuances of inheritance.
Of course I have no credibility. Credibility is something you have or don’t have when you are debating important topics with real outcomes. Architectural discussions in a real product for example. This post is just a little bit of thought-provoking fun :o)
Pingback: Bonnes pratique de codage en C#
I hate to be the only voice of Ruby in this thread, but I should let you know that one of the significant features of Ruby is that it is object oriented but it doesn’t have multiple inheritance, it shares implementations across an inheritance tree. Very similar to the Mix-in stuff I saw on your code page. Considering your background in Java and how much it looks like you’re enjoying Javascript interpreters, you might actually love Ruby, as it’s like java but executed as an interpreted language and without the need to compile and without the class inbreeding of evil inheritance. Ruby and Javascript function the way your post eludes other languages should.
Though I’m not sure the world is over how “cool” it was when it was the new guy. So I disclaim that I myself am a broad-facing-actor zealot. I Iove processing & processing.js right now, I’m inspired by openframeworks and I wonder when the world is going to really use RDFXML for something useful.
Pingback: Bonnes pratique de codage en C# « Hakanai
Every article on this subject always states that inheritance is bad, and then goes ahead to prove it by showing some examples of the bad use of inheritance? Anything useful can be used badly – give me a hammer and I’ll prove it.
As many people have said, use it correctly and it’s wonderful. Your jedi example fails because DarkPowers are, by definition, something that a Jedi “has”. This is your first clue not to use inheritance in this example. What’s more, if DarkHippo ever took it upon himself to use a lightsabre, he wouldn’t be able to, because DrawSabre is “locked up” in the Jedi class. Are you going to put every method you define in it’s own class? Obviously not.
You can’t prove that “is-a” relationships are bad by using them to model what should be “has-a” relationships, and then blowing the example apart. Use inheritance properly, understand what you’re doing, and there’s no problem.
Do you have an example that you would like to share where single inheritance is significantly more useful than has-a type implementations? I am genuinely interested.
You mean, “do I have an example that goes against the point I’m trying to make in the article?” ;o)
Yes, the Template Method Pattern – http://en.wikipedia.org/wiki/Template_method_pattern – is an excellent use of single inheritance. Technically you could use the strategy pattern in its place, but it would not be as flexible or intuitive.
Bernie :o)
Yes, and yes.. :)
It’s interesting that although this pattern is a very good case for inheritance, it still can be substituted for a more general interface, albeit at a bit of a cost as you mention. I suppose what I’m wondering (from the viewpoint of any taker) is: does this pattern warrant the use of inheritance, or can it be safely avoided with a wee bit of pain in very specific circumstances? I’m guessing the latter.
I’ve felt very similarly to the sentiment of the article title. It seems that I’m always trying to fit my code into the inheritance structure, rather than having it work for me. In fact, the majority of my code that doesn’t rely on environment specific classes, but tends to consist of shallow objects.
Hey guys, you should really look at what happens when functional elements are included in a language, such as in C# with extension methods. If you keep the “is-a” heirarchy smoothly supported by inheritance (as is its proper purpose), you can then still extend objects with functionality by adding extension methods. If combined with interfaces (blank, or just providing the required properties and methods) then you can mark an object as inheriting an interface and then extend that interface to add methods to all grouped objects. This can even be inserted from other assemblies, so black-boxed OO classes are still accessible for extension and effective duck-typing. You can always combine this by having a simple implementation that routes methods to a child object, so the interface define the child object, whilst a child object provides the implementations. This appears to provide a more complete range of solutions to suit all potentials than the limited set discussed here.
The “is-a” / “has-a” way of seeing things is OK, but to me it doesn’t explain what inheritance – and its “complement”: composition – is really meant for (at least, to me).
Inheritance allows you to specialize.
For instance: given your base class A implementing a few methods, you may (and certainly will) get to a point where A almost fits your needs, but for some (local) business logic reason, you’d need some of A’s methods to behave a bit (or completely) differently.
You could actually add more specific methods to A to fill the “gap”, but doing so, you’d just end up with a huge class full of methods that would be used in certain occasions only, which would be hard to maintain (and quite a naive approach).
You could also copy A, and turn it into another class B, then change the methods implementation where needed. This is OK (and quite logical) if you actually have to alter all the methods (which would imply that you’d actually need another, different class from A – and then inheritance would not be useful at all, even for “is-a” sort-of classification of classes). But if you really need say 95% of A, thus changing just 5% of it in B, you’ll end up with 95% code duplication (which is, again, not a good idea).
So, this is where inheritance is useful: it will help you specialize your B class by changing methods that need to behave differently but still benefiting from A’s methods that are the same. So, B (and all possible other children classes), will be similar to A in terms of “what they are” (properties and methods), but will differ in terms of “what they do” (methods implementation will be more specific in the children).
If you keep that in mind, you’ll use inheritance for what it is meant to do, thus will use it the right way and when needed only.
Quite a few developpers actually use inheritance with abstract classes only (and I tend to do so myself though not systematic): they just implement the methods that won’t require changes in the children, leaving the other ones empty (for future, specific, specialized implementation right into the children).
Now: inheritance is NOT meant to ADD things that don’t exist in the parent! This is, to me, a terminlogy issue with the term “extends”: you actually don’t extend anything with inheritance, in terms of new functionnalities, you just specialize (again, again, again…) the existing ones. If, beside specialization, you need to extend (ADD) functionnalities, then inheritance is not the good “tool” for this. Of course, you can do it, but this is that nice: what if the portion of code you add to B (child of A), is also required in its “sibling classes” C, D, K, P? Will you duplicate it? Hum.
To add new things, you’d better go with composition: put the “new” code elsewhere, in another class, then call it where needed in your specialized methods. Doing so will keep all your parented classes consistent AND will avoid code duplication (right now and/or in the future) whenever you need to add the same functionnalities in different places/classes (parented or not). The strategy pattern, cited in this article, is an interesting way of doing composition, and you should use it when it fits the needs. Of course, the use of design patterns must always be relevant to the actual need or problem, and not a systematic behaviour nor dicted by hype.
I see your point. However:
a) if the designer of the base class did not intend the methods to be overridden, then overriding them may create random odd bugs, but b) if the designer did intend the methods to be overridden, then they could just as easily define a strategy interface that you can use to pass in an object representing your intended customisations.
Hi Bernie
Thanks for your reply on this.
Well, I see your point too. Here are my thoughts.
a) if the designer of the base class did not intend the methods to be overridden, then overriding them may create random odd bugs,
Well, as for OOP “standards”, if you don’t explicitly “tell” that your methods must not be overwritten, you implicitly admit than they can, thus will certainly will, at some point.
So, if you know that this or this method should not be overwritten in children classes, then you have to do something accordingly. Making the method “private” will prevent overwriting (at least in Java, and PHP, as far as I know), but this will also prevent sub-classes to actually use it directly. This is when the “final” keyword comes in handy: it doesn’t tell who can use the method (like public, protected, private do), but that it must not me overwritten elsewhere. Don’t know how many common OOP-enabled have the “final” keyword, but you should use it wherever it is identified that the method should not be overwritten (ie. a Singleton base class, for instance).
It is within the “main” designer to think that out, to anticipate the use that will be made of their classes, so you have to be careful about that, and protect/hide attributes and methods that should stay unaltered, for example.
but b) if the designer did intend the methods to be overridden, then they could just as easily define a strategy interface that you can use to pass in an object representing your intended customisations.
“just as easily”, I’m not sure. Be careful with patterns, I mean: be clear with yourself about what they have been invented, tested, and approved for, and what you could potentially use them for. This is comlpetely different, and very often leads to misuse.
Keep in mind that the Strategy pattern is a form of IoC, first. And as every other pattern, it should be use to solve the problem it had been designed to solve, solely, when identified.
What is Strategy meant for? Very basically, and to turn it short, you can convoque the Strategy pattern as soon as you’re noticing that this class “knows or assumes or does to many things regargind what it’s being developed for”. It’s important to keep in mind that if the Strategy pattern, as an IoC pattern, does loosen coupling, it also brings some more overhead as you’ll have to instanciate and pass other objects then. Which meand that if you do this all the time, your application will do too many things even for simple tasks. Again, using patterns (and even less this or that pattern precisely) are not a panacea, they do well for very specific problems.
Now, imagine a (PHP) class “A” (again ^^), defining base methods, amongst which a very, very, basic one: [public] __toString(). And let’s say that you want it to be a bit more precise than just outputting “__CLASS__” (which, by the way, may be a problem in subclasses if you don’t use Relection or late static bindings), for instance “Class A object. Base class to handle this and that. Can be inherited”.
Classes B, C, D, E, F are children class. Specializing the toString() method in each subclass is very easy, and will cause no specific overhead.
Now imagine it via the Strategy pattern. Tough.
Even worse if, instead of this simple, always specific method, you only have one or two functions amongst say 6 or 10 that will really require specialization: you’ll convoke the Strategy pattern for all cases, even those that are always the same and not likely to change…
Really, I don’t think you can use Strategy where inheritance is the best answer. Call it where you need composition, say where you need not to specialize your classes but to add functionalities to them: this will be a real case where Strategy (and more generically, IoC), will be at its best use. I recently found on the web a pretty good Strategy example on a search engine (sort of) class. Whet it came to sorting, the developper felt that it had no real binding to searching, actually (and to me he was right). This was a typical case of both problems: “this class will need to know/do to more than it has on its own”, and “I may need sorting functionnality elsewhere in my application, not just into my search engine” => then, he pulled the sorting stuff out of the SE class, coded a sorting class, then was able to use the Strategy pattern to use it within its SE (or whatever). The big plus: whenever he needs a new way of sorting things, will be very easy, and he’ll need not to alter he’s SE code. Clearly (at least to me), this is when IoC patterns should be used.
Sorry for all the typos in my answer (made a lot)
Hope it’s still clear enough ^^
Hi Bernie,
I feel a bit like a spammer right now ^^
Speak so much that I forgot to mention something interesting (and important) as of patterns and inheritance: the Deocorator pattern.
Basically, it is sort of a substitute for sub-classing, but it should be used in some specific occasions only (as always with patterns).
Say: if the (modified) behavior has to to be added/removed at run time, or if you need to combine the functionalities from multiple decorators (where multiple inheritance is not possible, like in PHP, or not suitable nor wishable)
Sounds like the problem is a lack of Interfaces. DarkJediPowers should be an interface that anyone can implement.
Your Ball example actually works equally well with this!
Interfaces when all implementations are best represented using multiple inheritance of course. Then again in my experience it is rare that a DarkHippo is going to crush villagers in the same way a DarkJedi will. :)
I’m relieved that I’m not alone with my view of disliking inheritance.
And yes my main problem with it is that it’s against encapsulation as sy already wrote (I just couldn’t name the feeling).