State Pattern

Implement different actions on state changes in our program

The State Pattern is what is implemented under the hood in most of the popular web development, reactive frameworks like React JS, Angular JS, Next JS, Vue JS, Svelte JS and many others too !

Basically....

Given a situation where you want part of the program to behave differently based on the state of another part of the program, you use the state pattern

Eg : On clicking a internal page's link in a reactive web app, the main page component gets changed whereas the navbar and footer stay constant.

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 MS Paint, Photoshop, Sketch etc. in the sense that when a different tool (Brush, Selection, Eraser), a different function is executed when the mouse is moved up or moved down

Implementing the State

A common interface for 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


Type Name Function
Methods handleMouseUp Prototype of method for handling a "mouse up" event
handleMouseDown Prototype of method for handling a "mouse down" event
public interface Tool {
    void handleMouseDown();
    void handleMouseUp();
}
Tool.java

Implementing the class using these tools (Context)

We will just define class that just calls and accesses different tools based on different inputs from our side

Also, we will be using an enum to specify the different kind of tools that are available for use.

public enum ToolType {
    SELECTION,
    BRUSH,
    ERASER
}
ToolType.java
public class Canvas {
//  USING THE STATE PATTERN
    public Tool currentTool;

    public void mouseUp(){
        currentTool.handleMouseUp();
    }

    public void mouseDown(){
        currentTool.handleMouseDown();
    }

    public Tool getCurrentTool(){
        return currentTool;
    }

    public void setCurrentTool(Tool requiredCurrentTool){
        this.currentTool = requiredCurrentTool;
    }

}
Canvas.java

Implementing the ConcreteState classes

Child classes that extend the State interface by polymorphing the enlisted methods

Type Name Function
Methods handleMouseDown Tool-wise implementation of the "mouse down event". eg : brush tool will draw a downward arrow
handleMouseUp Tool-wise implementation of the "mouse down event". eg : eraser tool will erase something below it
public class BrushTool implements Tool{

    //@Override
    public void handleMouseDown() {
        System.out.println("Downward arrow drawn");
    }

    //@Override
    public void handleMouseUp() {
        System.out.println("Downward arrow drawn");
    }
}

BrushTool.java
public class SelectionTool implements Tool {
    //@Override
    public void handleMouseDown() {
        System.out.println("Selection Icon");
    }

    //@Override
    public void handleMouseUp() {
        System.out.println("Rectangular area selected !");
    }
}

SelectionTool.java
public class EraserTool implements Tool{
    //@Override
    public void handleMouseDown() {
        System.out.println("Eraser Icon");
    }

    //@Override
    public void handleMouseUp() {
        System.out.println("Erased some stuff !");
    }
}
EraserTool.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 using the Eraser Tool for demo but you can go with whichever tool you prefer out of the 3 that we have built

var canvas = new Canvas();
canvas.setCurrentTool(new EraserTool());
canvas.mouseDown();
canvas.mouseUp();
main.java

Conclusion

Congrats on unlocked the secret of how most reactive applications work under the hood. You should feel pretty comfortable now developing the state responsive functionalities 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.