State Software Design Pattern

October 10, 2024 note-to-self

The State Design Pattern is a behavioral design pattern that allows an object to change its behavior when its internal state changes. This pattern is particularly useful when an object needs to exhibit different behaviors based on its current state, without resorting to large conditional statements.

Key Concepts of the State Pattern

Context: The object whose behavior changes based on its state. It maintains a reference to a state object. State Interface: An interface that defines the methods that concrete state classes must implement. Concrete State Classes: Classes that implement the state interface, each representing a specific state of the context.

Benefits of the State Pattern

Single Responsibility: Each state is encapsulated in its own class, promoting the single responsibility principle. Open/Closed Principle: New states can be added without modifying the context or existing state classes. Simplified Code: Reduces the need for conditional statements to manage state transitions.

Example Implementation in PHP

Here's a simple implementation of the State Design Pattern in PHP, illustrating a context that represents a traffic light system with different states (Red, Yellow, Green).

// State Interface
interface TrafficLightState {
    public function change(TrafficLightContext $context);
}

// Concrete State Classes
class RedLight implements TrafficLightState {
    public function change(TrafficLightContext $context) {
        echo "Red Light: Stop.\n";
        $context->setState(new GreenLight()); // Change to Green
    }
}

class GreenLight implements TrafficLightState {
    public function change(TrafficLightContext $context) {
        echo "Green Light: Go.\n";
        $context->setState(new YellowLight()); // Change to Yellow
    }
}

class YellowLight implements TrafficLightState {
    public function change(TrafficLightContext $context) {
        echo "Yellow Light: Caution.\n";
        $context->setState(new RedLight()); // Change to Red
    }
}

// Context Class
class TrafficLightContext {
    private $state;

    public function __construct(TrafficLightState $state) {
        $this->state = $state;
    }

    public function setState(TrafficLightState $state) {
        $this->state = $state;
    }

    public function change() {
        $this->state->change($this);
    }
}

// Usage
$trafficLight = new TrafficLightContext(new RedLight());
$trafficLight->change(); // Red Light: Stop.
$trafficLight->change(); // Green Light: Go.
$trafficLight->change(); // Yellow Light: Caution.
$trafficLight->change(); // Red Light: Stop.