Strategy Pattern

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  :

State Pattern in Java
Understanding how the state-change-reactiveness of modern software is implemented by studying the state pattern

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.‌

crew-guy/Design-Patterns
A collection of the design patterns, implemented in java, as originally created by the GoF - crew-guy/Design-Patterns

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 !!🔥‌

Project Unified Modelling Language (UML) Diagram

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
public interface Compressor {
    void compress(String fileName);
}
Compressor.java (Interface aka Strategy 1)
public interface Filter {
    void apply(String fileName);
}
Filter.java (Interface aka Strategy 2)

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

public class ImageStorage {
    public void store(String fileName, Compressor compressor, Filter filter){
        compressor.compress(fileName);
        filter.apply(fileName);
    }
}
ImageStorage.java

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

public class JpegCompressor implements Compressor{
    @Override
    public void compress(String fileName) {
        System.out.println("Compressing "+ fileName +" using JPEG format");
    }
}
JpegCompressor.java
public class PngCompressor implements Compressor{
    @Override
    public void compress(String fileName) {
            System.out.println("Compressing "+ fileName +" using PNG format");
    }
}
PngCompressor.java
public class BandFilter implements Filter{
    @Override
    public void apply(String fileName) {
        System.out.println("Filtering " + fileName + "  using the RGB filter");
    }
}
BandFilter.java
public class RGBFilter implements Filter{
    @Override
    public void apply(String fileName) {
        System.out.println("Filtering " + fileName + "  using the RGB filter");
    }
}
JpegCompressor.java

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

The Ultimate Design Pattern Series
Ace your coding job interview. Learn to write maintainable and extensible code.