The State Pattern is a behavioral design pattern that allows an object to change its behavior based on its internal state. This pattern is particularly useful when an object needs to perform different operations depending on the context or state it's in. By encapsulating each state into a separate class, the State Pattern promotes loose coupling and makes the code more maintainable.
The core idea behind the State Pattern is to define a set of states that an object can be in, and encapsulate the behavior associated with each state within its own class. The context (the object whose behavior changes) holds a reference to one of these state objects at any given time. When the context's internal state changes, it transitions to a new state object, thereby altering its behavior.
State object and delegates requests to it.State interface and define the behavior associated with each state.Let's illustrate the State Pattern through a practical example: A traffic light system. The traffic light can be in one of three states: Red, Yellow, or Green. Each state has its own behavior (e.g., what happens next).
The TrafficLight class will act as the context and maintain a reference to the current state.
1class TrafficLight {2constructor() {3this.state = new RedState(this);4}56setState(state) {7this.state = state;8}910request() {11this.state.handle();12}13}
The State interface will define the methods that all concrete states must implement.
1class State {2handle() {3throw new Error('handle method must be implemented');4}5}
Each state (Red, Yellow, Green) will be a class that implements the State interface.
1class RedState extends State {2constructor(light) {3super();4this.light = light;5}67handle() {8console.log('Traffic Light is Red. Changing to Green.');9this.light.setState(new GreenState(this.light));10}11}1213class YellowState extends State {14constructor(light) {15super();16this.light = light;17}1819handle() {20console.log('Traffic Light is Yellow. Changing to Red.');21this.light.setState(new RedState(this.light));22}23}2425class GreenState extends State {26constructor(light) {27super();28this.light = light;29}3031handle() {32console.log('Traffic Light is Green. Changing to Yellow.');33this.light.setState(new YellowState(this.light));34}35}
Now, let's create a traffic light and simulate its behavior.
1const trafficLight = new TrafficLight();23trafficLight.request(); // Output: Traffic Light is Red. Changing to Green.4trafficLight.request(); // Output: Traffic Light is Green. Changing to Yellow.5trafficLight.request(); // Output: Traffic Light is Yellow. Changing to Red.
In the next section, we will explore another behavioral pattern called the Strategy Pattern. The Strategy Pattern allows you to define a family of algorithms, encapsulate each one, and make them interchangeable. This makes it easier to switch between different algorithms at runtime.
Stay tuned for more insights into design patterns and how they can help you write better code!