Strategy Pattern
Introduction:
Strategy pattern is a behavioral design pattern that lets you define a family of algorithms, put them into separate classes, and make their objects interchangeable.
Scenario,
We are building the navigation app for travelers. The functionality of the app is to provide the fastest route from source to designation. Initially decided to provide the support only for four wheelers. Later customer requested to add support for public transport, pedestrians (by walk), and so on.
The technical part of maintain the code became very difficult since we keep adding the new routing algorithms into the main navigation class. Navigation class size increased , also became difficult to extend further for new algorithms.
Strategy pattern helps to resolve this issue by creating a new strategy abstract class and define all these algorithms into separate derived class from abstract strategy class.
Context class holds the object of the strategy class. Context class delegates the work to the linked strategy class. Context class is not responsible to select strategy. Client should know the different types of strategies, and client should choose the strategy class based on the user request and pass it to context class.
In this way, the main class(navigation class/context class) is decoupled from the strategy class, and strategy class can be extended further to add routing algorithm without modifying the context class.
When to use,
- When we need to have different variants of algorithms within the object, want to switch between algorithms during runtime.
- Use strategy pattern when we have lot of classes only differ in the way they operate.
- When the code has massive conditional statements that switches between the different variants of the same algorithm.
How to use,
- Define strategy abstract class, and declare strategy interface common to all the variants of the same algorithm.
- Extract all variants of the algorithm from its class, and add it as separate derived class under strategy abstract class.
- Define Context class and provide storage field to hold reference of strategy class object. Also define setStrategy() method to replace the strategy object in the runtime.
- Client of the context class should set the strategy based on how it expect context class to work.
UML diagram:

Implementation:
Write an application to provide best route from source to destination based on the user selection.
Sourcecode: https://github.com/krishnaKSA/design_patterns_cplusplus/blob/main/StrategyPattern/StrategyPattern.hpp
Class Diagram:
Strategy interface class:
//Strategy abstract class
class IRouteStrategy
{
public:
virtual void buildRoute() = 0;
};
Concrete strategy classes:
//concrete strategy class
class FourWheelerStrategy: public IRouteStrategy
{
public:
void buildRoute()
{
cout<<"FourWheelerStrategy route projected to the user"<<endl;
}
};
//concrete strategy class
class PublicTransportStrategy: public IRouteStrategy
{
public:
void buildRoute()
{
cout<<"PublicTransportStrategy route projected to the user"<<endl;
}
};
//concrete strategy class
class WalkStrategy: public IRouteStrategy
{
public:
void buildRoute()
{
cout<<"WalkStrategy route projected to the user"<<endl;
}
};
Context class:
//context class
class Context
{
private:
IRouteStrategy* strategy;
public:
Context():strategy(nullptr)
{
}
//Set strategy
void setStrategy(IRouteStrategy* strategy)
{
this->strategy = strategy;
}
//Build route based on the strategy selected
void buildRoute()
{
if(nullptr != strategy)
{
this->strategy->buildRoute();
}
else{
cerr<<"No strategy selected "<<endl;
}
}
};
Application:
//Class Application
class Application
{
std::string userChoice;
Context* context;
public:
Application(Context* context)
{
this->context = context;
}
//user selection
void findRoute(string selectedOption)
{
if("car" == selectedOption)
{
this->context->setStrategy(new FourWheelerStrategy);
}
else if("walk" == selectedOption)
{
this->context->setStrategy(new WalkStrategy);
}
else if("bus" == selectedOption)
{
this->context->setStrategy(new PublicTransportStrategy);
}
else{
//do nothing
}
this->context->buildRoute();
}
};
Client code:
void testClientCode()
{
Context* obj = new Context();
Application* appl = new Application(obj);
appl->findRoute("bus");
appl->findRoute("walk");
appl->findRoute("car");
}