The first pattern I want to talk about is the Strategy pattern, which always reminds me about the Command & Conquer games so I'll simply use it as an example :)

First of all, the definition: "Define a family of algorithms, encapsulate each one, and make them interchangeable. Strategy lets the algorithm vary independently from clients that use it."

I'm bad at remembering definitions or trying to imagine what they really mean, so let's just go ahead and try to create something and learn as we go, eventually we'll end up implementing the Strategy pattern and you'll 'get it' for the rest of your life, without a definition.

A long time ago, we made a simple strategy game, having only 2 units, a soldier and a tank, both were able to shoot at each other which we implemented as follows:

Simple Class Model

The Shoot() logic is contained in the base GameUnit class, since it's identical for both units. Each unit takes care of drawing itself.

After a while, we receive a request to add in an Engineer, which is a unit used to take over buildings and more importantly, he can't shoot.

If we just added an Engineer class similar to the Soldier one, he would be able to shoot as well, which we don't want. We could for this once just override the Shoot() method for the Engineer and make it empty.

Hiding methods - Maintenance Hell

Can you already see where this is going to end up? Maintenance Nightmare!

Eventually we end up with lots of useless code being repeated for every class which has a different shooting logic, where you have to open up every class to figure out all the available implementations. Let's not implement it like this!

What if we were to get rid of the Shoot() logic in the GameUnit class and make an IShootable interface for the units that can actually shoot?

Interface - Code Duplication

That looks a bit cleaner, but wait! We simply shifted the nightmare, because now the Soldier and Tank have identically the same code in their Shoot() method. This isn't the solution either, let's take a look at what our higher level goal actually is.

We can see the part that changes is how a unit shoots. If we take a closer look at shooting and implementing future classes, it is very possible we'll end up with a class that has a very different shooting algorithm or has upgradeable parts, changing the way it shoots. You could say the way a unit shoots is a behaviour of a unit.

Remember the definition of the Strategy pattern? The shooting behaviour we have just defined is actually an algorithm, while the requirement of units being able to get upgraded implies the behaviours have to be changed at run time, making them interchangeable.

Making things interchangeable usually means having less things hard-coded in your application, which reminds of a great saying: Program to an 'interface', not an 'implementation'.

Let's separate all our shooting logic from our units and create a totally new set of classes defining all possible shooting behaviours.

Behaviour Set - Family of Algorithms

Now it's only a matter of letting our GameUnit use these behaviours. We'll do this by programming against the IShootingBehaviour interface instead of against an implementation. This way we can dynamically replace the behaviour at run time, and have a very flexible programming model towards the future.

Adding a new way of shooting is simply a matter of adding a new class implementing the IShootingBehaviour interface after which all our units could use it.

Strategy Pattern

And that's it! We've implemented the Strategy pattern. We defined a family of algorithms (IShootingBehaviour), we encapsulated each one (NormalShot, CantShoot, ThrowKnifes) and made them interchangeable (ShootingBehaviour property).

Each client can define his algorithm as we currently did in the constructor, by setting the property to the desired implementation. In a future pattern we'll see how to set this different, since it's not that pretty doing it in the constructor.

Note that even though we are setting a shooting implementation via the constructor, it is possible to change the way a unit shoots at runtime by setting the ShootingBehaviour property.

I've uploaded the sample project I have used while learning this pattern so you can have a look at the code representing the above diagrams yourself.

Some additional information on the Strategy pattern:

Reacties: 17
  • Great post! Glad to see you're back at blogging.

  • This might be a dumb question, but which tool do you use to draw these beautiful UML diagrams?

  • That would be Visual Studio 2008, it's in 2005 as well. You add a new item, pick class diagram (.cd as extension) and you just drag your classes on the designer, or your source files.

    I'm in love with it, slick looking diagrams without much effort ;)

  • That's what I feared. I use Eclipse on a Mac for Java development :-(

    Very nice article, anyway. You should create a printer friendly version or, better, a PDF file.

  • Mohammed Yousuff

    thanks a lot for best explanation about the Strategy Pattern , expecting more patters from your end. thanks a lot

  • Tom

    Great article. Thanks

  • The Print Preview in Firefox looks quite ok, the HTML behind this blog is made so that content is on top whenever you print, without the side menu.

    Just limit the number of pages you print to stop when the comments start :)

  • Siva

    Thank a lot for explaining Strategy Pattern in most simple way possible. Appreciate your efforts.

  • tieTYT

    This is a good way to teach patterns in general. Thanks.

  • woww,your strategy is very good example.

  • This is a great explanation and example of the Strategy pattern!

  • Thanks for the tutorial! I really like the step-by-step explanation of *why* you'd want to use this pattern opposed to "the first thing that comes to mind". The diagrams were very useful also.

  • Karuna

    I am really thankful for ur help..

  • Rajesh

    Good post, helpful in understanding and remembering DPs for a newbie like me :)

  • rajeshMR

    good examples thnaks dear

  • amol

    Very well explained.Thank you

  • Yuksel DASKIN

    Hi, thanks for such a great example!
    ps: don't forget to fix last diagram, i think game units like soldier should have shootingbehavior property.

  • Reageer
    Items aangeduid met * zijn verplicht. (Naam, Email, Commentaar)
    Enkele items ontbreken of zijn fout ingevuld.
    Om zeker te zijn dat je geen computer bent, typ de onderstaande tekst over.