What
Strategy Design pattern is a type of behavior pattern. This pattern is mainly used for an application which needs to support families of algorithm. Basically, it enables a client to consume an application with many algorithms very easily.
It create hierarchy of algorithms and embeds them inside a strategy class. After that the client shall interact with only with strategy class. Due to separate hierarchy for algorithms, if more algorithm get added or existing get updated, it will not impact client.
In summary, an application using strategy design pattern is very easy to adapt to support new algorithms.
Why
Let us try to understand the need of strategy design pattern by taking an application whose job is to play video on computer screen.
Application need to take care of different video formats in order to play videos on computer.
Below are the some samples of video formats which the application may support:
- MP4
- AVI
- HD video
- Ultra HD video
Generally, the video formats mainly differs on video input video stream encoding mechanism. However, a specific video stream encoding again depends on video height and width. For selecting any video format need to give input for height and width also.
Sample application without Startegy design pattern
Below is the sample application without using Strategy design pattern. Here, we have abstract class VideoFormat with which the client is directly interacting.
#include<iostream> //main header
using namespace std;//for namespace
class VideoFormat
{
public:
virtual void playVideo()=0;
};
class AVI: public VideoFormat
{
public:
AVI( string encodingFormat, int height, int weight)
{ }
void playVideo()
{
cout<<" AVI format video playing"<<endl;
}
};
class HD: public VideoFormat
{
public:
HD(string encodingFormat, int width)
{ }
void playVideo()
{
cout<<" HD format video playing"<<endl;
}
};
int main()
{
AVI a1("AVI encoding", 700, 780);
a1.playVideo();
HD h1("HD encoding",1200);
h1.playVideo();
return 0;
}
As seen above, the client is directly interacting with 2 video formats. Therefore, the client need to understand the video formats and need to select properties as given below also:
- Encoding mechanism “AVI encoding” or “HD encoding”
- height or width
Hence, with above approach, the client needs to keep adapting if newer video algorithms are added. Finally, the client and algorithm remain directly linked to each other.
In order to solve above problem we need a design pattern which creates loose coupling between client and class video format.
How
In order to solve above problem with Strategy pattern we need to follow below rules:
Strategy Wrapper Class
Firstly, create a Strategy wrapper class which shall hold pointer to video format class.
Below is code snippet of the new Strategy wrapper class
class StrategyVideo
{
private:
VideoFormat *m_f1;
};
Expose interface to set strategy
The strategy class shall expose interface for client to select strategy. Therefore, this will let strategy class to handle all complexity of the video algorithm, such as height, width, encoding format, etc.
class StrategyVideo
{
private:
StrategyVideo *m_f1;
public:
void setStrategyVideo( Video_Type vtype) { }
};
Updated application using Strategy design pattern
#include<iostream> //main header using namespace std;//for namespace class VideoFormat { public: virtual void playVideo()=0; }; class AVI:public VideoFormat { public: AVI(string encodingFormat, int height, int weight) { } void playVideo() { cout<<" AVI format video playing"<<endl; } }; class HD: public VideoFormat { public: HD( string encodingformat, int width) { } void playVideo() { cout<<" HD format video playing"<<endl; } }; enum Video_type { AVI_VIDEO, HD_VIDEO }; class StrategyVideo { VideoFormat *m_vf; public: void setStrategyVideo(Video_type vtype) { switch(vtype) { case AVI_VIDEO: m_vf = new AVI("AVI",700,780); break; case HD_VIDEO: m_vf = new HD("HD",1200); break; } } void playVideo() { m_vf->playVideo(); } ~StrategyVideo() { delete m_vf; } }; int main() { StrategyVideo SV1; SV1.setStrategyVideo(AVI_VIDEO); SV1.playVideo(); StrategyVideo SV2; SV2.setStrategyVideo(HD_VIDEO); SV2.playVideo(); return 0; }
As seen above, with Strategy design pattern, now the algorithms and client are independent. It is very easy to introduce new algorithms and update existing also. There is no tight coupling between user and application.
Pros and Cons for Strategy design pattern
Pros
- Firstly, it becomes is easy for application to introduce algorithms dynamically.
- Moreover, the client do not directly depend on algorithms.
Cons
- Design is not easy due to introduction of new class.