Strategy Design Pattern

What is Strategy Pattern?

Strategy Lol GIF by MASTERPIECE | PBS

Strategy is a behavioral design pattern. This pattern helps you define different algorithms that can be applied in given circumstances into it’s own class and make their objects interchangeable.

Can you help me understand what type of problem we can solve with Strategy Pattern?

Let’s consider one example:

One day you decided to create app for cab service. A user will enter his current location and destination location where he wants to go and user will then get to see all nearby cabs, approximate price and time to reach to his destination. 

cab vogue clips GIF

You wrote all this code in TransportBookingService class.

  • The first version of the app was very successful, people used your app to book cabs, and traffic to your app kept increasing.
  • Over time, you thought to add the Auto-Rickshaw option also to your app.
  • And then you thought about adding an option to add Motor-Cycle option also.
  • This was just the starting as you had further plans to add public transport to your app, and ever personal vehicles.
  • Also, note that based on Transport type (MotorCycle or Cab or Auto-rickshaw) logic to find route and cost is very much different.

The developer kept adding logic with if-else statements in TransportBookingService class. It was getting even difficult to look at that big class of more than 5000 lines of code. 

class TransportBookingService {
  …
  public Response bookVehicle(currentLocation, destinationLocation, modeOfTransportation) {
    if(modeOfTransporation == “cab) {
      ….
      ….
    } else if (modeOfTransportation == “auto-rickshaw”) {
      ….
      ….
    } else if …
    } else if …
    } else if …
  }
}
// Response object will have list of vehicles, route information and price information. 

Even a single change in that class, used to give developers shiver that what if they break any other mode of transportation logic. Developers have to work on that class sequentially or have to suffer pain of merge conflicts.

Shocked Ubisoft GIF by Rabbids

We have created a beast.

boris karloff frankenstein GIF by Maudit

How can I use Strategy Pattern in the above case?

As per Strategy pattern, if you have a class which have algorithms placed under if-else condition, which will take same input parameters but do things differently, you should extract those algorithms into separate classes called as strategies.

So we should extract logic to:

  • BookCabStrategy
  • BookAutoRickshawStrategy
  • BookMotorCycleStrategy
  • BookPublicTransportStrategy

The original class, in this case TransportBookingService is called context is still the class with which client or other class will interact, but context will delegate the call to one of the strategies instead of containing the code for all strategies.

To make it happen, all of the strategy should have common interface, let’s call it TransportStrategy with method bookTransport.

public interface TransportStrategy {
  Response bookTransport(currentLocation, destinationLocation);
}

Context will store reference to strategy and call bookTransport method on strategy.

Now you can add more strategies or update existing strategy, without effecting other strategies or context code.

Can you write the complete Pseudocode for this?

code GIF
interface TransportStrategy {
  Response bookTransport(currentLocation, destinationLocation);
}
 
class Response {
  List<Vehicle> vehicles;
  Float price;
  Time timeToDestination;
}
 
class BookCabStrategy implements TransportStrategy {
  Response bookTransport(currentLocation, destinationLocation) {
    ….
    ….
  }
}

class BookAutoRickshawStrategy implements TransportStrategy {
  Response bookTransport(currentLocation, destinationLocation) {
    ….
    ….
  }
}
 
class BookMotorCycleStrategy implements TransportStrategy {
  Response bookTransport(currentLocation, destinationLocation) {
    ….
    ….
  }
}
 
class BookPublicTransportStrategy implements TransportStrategy {
  Response bookTransport(currentLocation, destinationLocation) {
    ….
    ….
  }
}
 
class TransportBookingService {
 
  private TransportStrategy strategy;
 
  public setStrategy(TransportStrategy strategy) {
    this.setStrategy = strategy;
  }
 
  public Response bookTransport(currentLocation, destinationLocation) {
    return strategy.bookTransport(currentLocation, destinationLocation);
  }
 
}

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s