Used to represent and execute different kinds of behaviors (like algorithms, functions) based on different strategy object
The Strategy Pattern is implemented to perform different behaviors represented from context object using the strategy object(s)
It is what is being currently used in a lot of places, substituting the State Pattern to follow the modern practice of decentralization of state into smaller components for a more robust component architecture in most frameworks like React JS, Next JS etc.
In fact, React JS Hooks, which got introduced in 2016 and took the component driven framework world by a storm, implement the Strategy Pattern logic under the hood !
Feel free to browse through this detailed blog on State Pattern for reference :
So how is this any different from the State Pattern ?
STATE PATTERN | STRATEGY PATTERN |
---|---|
Used to change behavior of the context object in different situations | Used to change behavior of the context object in different situations |
The context object can have only a single state and all its different behaviors are represented by sub-classes of the State interface so the state is centralised | The context object can have multiple states in the form of strategy objects implementing the Strategy interface, thus, different behaviors can be executed separately, independently due to the decentralised state |
eg : state management in class components in React JS which changes the entire state together | eg : state management in functional components in React JS to change and manage individual state properties |
Resources
The source code for all prominent design patterns has been properly implemented and documented in this GitHub repostitory by me.
Project Description
Here, in this article, we will be building a simple application that mimics digital illustration softwares like Photoshop, Gimp etc. in the sense that when a different img processing format (eg : JPG, PNG) and a different filtering strategy (eg : Black and White filter, RGB filter ) is implement, different functions are fired !!🔥
Implementing the Strategies
A strategy is just common interface for exposing a multitude of functionalities offered by our software
It can be either implemented as an abstract parent class or as an interface in all OOP languages. It just has to enlist the methods that all classes extending it have to polymorph in their own way for providing the - "same interface - different function" feature.
This choice is made simply by asking : Do I want my functionalities to have some code in common apart from the definition of their methods ? If yes, then implement state as an abstract parent class otherwise implement it as an interface
We have defined 2 strategies - Compressor and Filter, each with their own prototype method defined for compressing and filtering images.
Strategy Name | Protoype Name | Function of Prototype |
---|---|---|
Compressor | compress() |
Prototype of method for implementing the compression of an image |
Filter | apply() |
Prototype of method for implementing the filtering of an image |
Implementing the class using these tools (Context)
We will just define class that just calls and accesses different strategies based on different inputs from our side
Implementing the ConcreteStrategy classes
Child classes that extend their respective Strategy interface and implement the abstracted prototype methods listed by the interface that they extend
Strategy Name | Concrete Strategy Name | Function |
---|---|---|
Compressor | JpegCompressor |
Implementation of the compression the image by the JPEG algorithm |
PngCompressor |
Implementation of the compression the image by the PNG algorithm | |
Filter | BandFilter.java |
Implementation of the filtering the image by the Black and White filter |
RGBFilter.java |
Implementation of the filtering the image by the color filter |
Using this pattern in our application
Import all the necessary classes and modules into main.java for a final showdown of our application ! Here, I'll be storing images using just 2 permutations of selecting a Compressor and Filter options available but you can go with whichever option you prefer
var imageStorage = new ImageStorage();
imageStorage.store("image1",new JpegCompressor(), new BandWFilter());
imageStorage.store("image1",new PngCompressor(), new RGBFilter());
Conclusion
Congrats on unlocked the secret of how most modern implementations of reactive applications work under the hood. You should feel pretty comfortable now developing the state responsive functionalities in a decentralized but structured manner in your applications. Until next time...
References..
Whatever I have learnt and implemented here in code as well as the explanation is all from the teachings of the brilliant Mosh Hamedani and his course on Design Patterns which I would recommend you to take if you are really interested in exploring the beauty of Object Oriented Programming