Click here to Skip to main content
Click here to Skip to main content

Implementing a Motor Race Using the Strategy Pattern

, 15 Jun 2006 CPOL
Rate this:
Please Sign up or sign in to vote.
An article that explains the Strategy Pattern by giving an example of designing a motor racing game.

Introduction

In this article, we will learn about the Strategy Pattern by implementing it on a motor racing game. Strategy pattern is one of the many design patterns defined by the Gang of Four (GoF). A design pattern is a definition of a problem that other developers have faced before you, and they found a solution that might help you if you’re facing the same problem or a similar one. To know more about design patterns, please visit the www.dofactory.com site.

Background

Strategy pattern is used when you have objects that have many things in common but they also have different ways of behavior in certain situations. In this article, we'll design a small game (Motor Race), and we'll use Strategy pattern to implement the design. Again, this design is inspired by a solution that previous developers faced before and where they came up with this design pattern.

Game description

The game is a racing between different mobility motors; cars, motor-bikes, and buses; they all have many shared properties and behaviors, like, Motor Name, Color, but they also have different behaviors on certain points, like: the way that they look and get displayed, or the way they move. Cars and buses move on four wheels, but motor-bikes move on two wheels. The game will have many cars, motor-bikes, and buses racing. All the cars will have the same appearance, the same applies for motor-bikes and buses. Our goal now is to put a design for this game to be used in the client code, keeping in mind that we want our design to be reusable, meaning that if any time I decide to add a new mobility option (like a bike), I don’t want to rewrite the code for it, I'd just want to add the minimum amount of code and reuse the code that is already written. We also need our design not to have any redundant code, meaning if I have a code segment that is repeated in different places, I should group them in one place. Another thing to mention is that we’ll use C# to implement our design.

Using the code

First of all, let’s agree that we have three different types of objects that belong to the same group, and they have things in common; cars, motor-bikes, and buses are all mobility motors, so why don’t we make just one class for all of them and call it MobilityMotor and put all the shared properties in it, and then inherit this class into Car, MotorBike, and Bus? But the pattern doesn’t say so, because it's a better practice to implement an interface rather than extend and inherit a class, so what we should do now is create an interface and call it IMobilityMotor, putting the shared properties and methods there:

// Code 1

using System;
namespace MotorRace

{
    public interface IMobilityMotor
    {
       // We will add new property later in this
       // article to set the moving behavior of the object
       string MotorName
       {
               get;
               set;
       }
       string MotorColor
       {
               get;
               set;
       }
       void Move();
       void Display();
    }
}

Now, let's implement this interface three times, one for a Car class, one for a MotorBike class, and one for a Bus class. I'll show here how to make a Car class, and you can do the same for the MotorBike and Bus classes.

// Code 2

using System;
namespace MotorRace
{
    public class Car : IMobilityMotor
    {
       private string motorName;
       private string motorColor;
       // We will add new property later in this article
       // to set the moving behavior of the object
       public Car()
       {
           motorName = string.Empty;
           motorColor = string.Empty;
       }
       public string MotorName
       {
           get
           {
               return motorName;
           }
           set
           {
               motorName = value;
           }
       }
       public string MotorColor
       {
           get
           {
               return motorColor;
           }
           set
           {
               motorColor = value;
           }
       }
       public void Move()
       {
           // We will add code later
           // in this article to move object
       }
       public void Display()
       {
           // Add code here to display car,
           // this code is only for car objects
       }
     }
}

Now, just create two new classes for MotorBike and Bus, doing the same as you did for the Car. You will end up with a result that’s shown in the diagram below. Don't pay attention now to the MovingBehavior property in the MotorBike, Car, and Bus classes, you’ll understand it later in this article.

And now, we want to create classes to implement the moving behaviors, so we’ll create an interface and call it IMovingBehavior. This interface will be implemented by two classes: FourWheelsMoving and TwoWheelsMoving, and it will contain a Move() method that will be implemented by the two classes, as follows:

// Code 3

using System;
namespace MotorRace
{
    public interface IMovingBehavior
    {
        void Move();
    }
}

Now, let’s implement the IMovingBehavior interface by the FourWheelsMoving class, and then also by the TwoWheelsMoving class.

// Code 4
using System;
namespace MotorRace
{
    public class FourWheelsMoving : IMovingBehavior
    {
       public FourWheelsMoving()
       {
       }
       public void Move()
       {
            // We will add code later
            // in this article to move object
       }
    }
}

Let’s now understand what we have done. We have created two interfaces: one for a mobility motor (cars, motor-bikes, and buses), and another one for the way they move. As we mentioned before, there are two ways to move, either on four wheels or on two wheels. So, we implemented two classes from the IMovingBehavior interface, and we implemented three classes from the IMobilityMotor interface. In this design, we implement a high level of reusability, so if we need to add a new motor in the future, for example, a bike, or a lorry, all that we need to do is to implement a new class for it from IMobilityMotor, and if we have a new motor that moves on three wheels, or a motor that flies like a helicopter, then we just implement a new behavior class from the IMovingBehavior interface.

But the question now is how will a Car object know what its behavior is and the way it should move? To solve this, let’s add a new property to IMobilityMotor to set the correct behavior, and we’ll also add an implementation of this property in the Car, MotorBike, and Bus classes, as follows:

// Code 1 (Updated)

using System;
namespace MotorRace
{
    public interface IMobilityMotor
    {
       // We will add new property later in this
       // article to set the moving behavior of the object
       IMovingBehavior MovingBehavior
       {
           get;
           set;
       }
       .
       .
       .
       .
// Code 2 (Updated)
using System;
namespace MotorRace
{
   public class Car
   {
       private string motorName;
       private string motorColor;
       // We will add new property later in this
       // article to set the moving behavior of the object
       IMovingBehavior movingBehavior;
       public IMovingBehavior MovingBehavior
       {
           get
           {
                   return movingBehavior;
           }
           set
           {
                   movingBehavior = value;
           }
       }
       .
       .
       .
       .
       .

Now, we should implement the Move() method in the Car, MotorBike, and Bus classes, as follows:

// Code 2 (Updated)
using System;
namespace MotorRace
{
    public class Car
    {
       .
       .
       .
       .
       .
       public void Move()
       {
           movingBehavior.Move();
           /* Here, the Car object will know that
              movingBehavior is of type 
              FourWheelsMoving, because when its value was set
              it was initiated to FourWheelsMoving instance, 
              so when we call the Move() method, 
              it will call the Move() method 
              in FourWheelsMoving class. */
       }
       .
       .
       .
       .
       .

Conclusion

So we can now get to this conclusion: the Strategy pattern defines a family of algorithms, encapsulating each one by grouping similar algorithms in one place and separating the parts that vary.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Mohammad Abu-Ali
Software Developer (Senior) Software Café
Jordan Jordan

Comments and Discussions

 
GeneralMy vote of 1 Pingroupmesi_cs9-Feb-11 4:49 
Questioncan u give example pics? Pinmemberkampon6-Dec-07 15:02 
AnswerRe: can u give example pics? PinmemberMohammad Abu-Ali7-Apr-08 4:45 
GeneralInversion of Control Pinmemberc4tes16-Jun-06 6:00 
GeneralFix your code samples [modified] Pinmemberdannomight2-Jun-06 4:37 
AnswerRe: Fix your code samples [modified] PinmemberMohammad Abu-Ali5-Jun-06 1:24 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web04 | 2.8.141022.1 | Last Updated 15 Jun 2006
Article Copyright 2006 by Mohammad Abu-Ali
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid