Example of State Pattern in C++

Problem Statement:

We have to design a simple traffic light system. The traffic light system consists of different states: Red, Yellow, and Green and the behavior of the traffic light is determined by its current state.

Key Components of the State Pattern in C++

The State Pattern consists of the following key components:

  • Context: This is the class that has a state and assigns the state-specific behavior to different state objects.
  • State: The abstract base class or interface that defines a common interface for all concrete states. Each concrete state implements specific behaviors associated with a particular state.
  • ConcreteState: These are the classes that inherit from the State class and provide the specific implementations for the behaviors associated with a particular state.

Implementation of above State Pattern in C++:

TrafficLightState(State Interface):This is an abstract class that serves as the interface for all concrete states. It declares a pure virtual function “handle()”, which is responsible for defining the behavior of a particular state.

C++




// State Interface
class TrafficLightState {
public:
    virtual void handle() = 0;
};


RedState, YellowState, GreenState(Concrete States):These are the concrete classes that implement the “TrafficLightState” interface. Each class provides a specific implementation for the handle() function, representing the behavior associated with the corresponding traffic light color.

C++




// Concrete States
class RedState : public TrafficLightState {
public:
    void handle() override {
        std::cout << "Traffic Light is Red\n";
    }
};
 
class YellowState : public TrafficLightState {
public:
    void handle() override {
        std::cout << "Traffic Light is Yellow\n";
    }
};
 
class GreenState : public TrafficLightState {
public:
    void handle() override {
        std::cout << "Traffic Light is Green\n";
    }
};


TrafficLight(Context):The TrafficLight class has a member variable state of type TrafficLightState*, representing the current state of the traffic light. Initially, it sets the state to a default state (in this case, RedState).

  • “setState(TrafficLightState *newState)” function allows changing the current state to the specified state.
  • “change()” function invokes the “handle()” function of the current state, effectively executing the behavior associated with that state.

When the change() function is called, it invokes the handle() function of the current state (state->handle()).Since the state is initially set to RedState, the first invocation of change() prints “Traffic Light is Red.”When the state is later changed to GreenState using setState(new GreenState()), then, the next time change() is invoked it prints “Traffic Light is Green,” showing the updated behavior of the new state.

C++




// Context
class TrafficLight {
private:
    TrafficLightState *state;
 
public:
    TrafficLight() : state(new RedState()) {}
 
    void setState(TrafficLightState *newState) {
        delete state;
        state = newState;
    }
 
    void change() {
        state->handle();
    }
};


Main Function:An instance of “TrafficLight” is created, and its initial state is “RedState”.The “change()” function is called, and it prints “Traffic Light is Red” since the initial state is “RedState”.The state is then changed to “GreenState” using the “setState(new GreenState())” function.The “change()” function is called again, and it prints “Traffic Light is Green,” reflecting the new state.

C++




int main() {
    TrafficLight trafficLight;
 
    trafficLight.change();  // Initial state: Red
    trafficLight.setState(new GreenState());
    trafficLight.change();  // State changed to Green
 
    return 0;
}


Below is the complete combined code of the above example:

C++




#include <iostream>
 
// State Interface
class TrafficLightState {
public:
    virtual void handle() = 0;
};
 
// Concrete States
class RedState : public TrafficLightState {
public:
    void handle() override
    {
        std::cout << "Traffic Light is Red\n";
    }
};
 
class YellowState : public TrafficLightState {
public:
    void handle() override
    {
        std::cout << "Traffic Light is Yellow\n";
    }
};
 
class GreenState : public TrafficLightState {
public:
    void handle() override
    {
        std::cout << "Traffic Light is Green\n";
    }
};
 
// Context
class TrafficLight {
private:
    TrafficLightState* state;
 
public:
    TrafficLight()
        : state(new RedState())
    {
    }
 
    void setState(TrafficLightState* newState)
    {
        delete state;
        state = newState;
    }
 
    void change() { state->handle(); }
};
 
int main()
{
    TrafficLight trafficLight;
 
    trafficLight.change(); // Initial state: Red
    trafficLight.setState(new GreenState());
    trafficLight.change(); // State changed to Green
 
    return 0;
}


Output

Traffic Light is Red
Traffic Light is Green



Diagrammatical Representation of the State Pattern in C++

  • The “TrafficLight” class acts as a context that has a state. The state can be changed using the “setState” method.
  • The “TrafficLightState” is an abstract class that defines the common interface for all concrete states. It declares the “handle()” method, which represents the behavior associated with a specific state.
  • The “RedState”, “YellowState”, and “GreenState” classes are concrete implementations of states. They inherit from “TrafficLightState” and provide specific behaviors for handling the traffic light in different states.
  • The “TrafficLight” class interacts with the current state through the “handle()” method, which allows the traffic light to exhibit different behaviors based on its internal state.

This diagram illustrates how a traffic light can change its behavior (color) by transitioning between different states (Red, Yellow, Green). Each state class defines what should happen when the traffic light is in that specific color. The “TrafficLight” class manages the state and delegates the handling of behaviors to the current state.

State Method Design Pattern | C++ Design Patterns

In software design, managing the behavior of an object according to its internal state is a common issue. The state pattern addresses this issue by allowing an object to alter its behavior every time its internal state changes.

This pattern encapsulates each state in a separate class, which makes it easier to add new states and modify existing states without altering the object’s code directly. This pattern is useful when an object transitions between different states, with each transition triggering specific actions.

Important Topics for the State Method Design Pattern in C++ Design Patterns

  • Example of State Pattern in C++
  • Advantages of the State Pattern in C++ Design Patterns
  • Disadvantages of the State Pattern in C++ Design Patterns
  • Conclusion

Similar Reads

Example of State Pattern in C++

Problem Statement:...

Advantages of the State Pattern in C++ Design Patterns

...

Disadvantages of the State Pattern in C++ Design Patterns

...

Conclusion

...