# Use the State Pattern to alter the behaviors of a Hero

In this post, I will use the State Pattern to alter the behaviors of a hero when it is under attack or being silenced. State pattern allow us to encapsulate states into separate classes and delegate behaviors to the object representing the current state.

See code at Github repo (https://github.com/yangju2011/design-patterns). Code is adapted from Head First Design Patterns: A Brain-Friendly Guide 1st Edition by Eric Freeman and Elisabeth Robson.

# State Pattern

## Definition

Allows an object to alter its behaviors when its internal state changes. The object will appear to change in class. It encapsulates states into separate classes and delegates behaviors to the object representing the current state.

## State pattern and state machine

These two concepts are closely related and sometimes used interchangeably. However, they are different in their focus.

• State pattern abstracts the states and focuses on varying behaviors of a state. It doesn’t mean to address the transition.
• State machine abstracts the state diagram and focuses on the transition between states. It doesn’t mean to address the behaviors in each state.

See Wikipedia and StackOverflow.

## HeroStateV1

In this example, a Hero can be in one of the 3 states: ALIVE, DEAD, SILENCED defined in HeroContext

When a Hero is ALIVE with hp>0, it can attack, and can be attacked and silenced.

• When attacked, its hp is decreased by damage. If hp<=0, a Hero enters the state of DEAD with hp=0.
• When silenced, a Hero enters the state of SILENCED.

When a Hero is DEAD with hp=0, it can be revived.

• When revived, a Hero enters the state of ALIVE with full hp.

When a Hero is SILENCED, it can be attacked and recovered.

• When attacked, its hp is decreased by damage. If hp<=0, a Hero enters the state of DEAD with hp=0.
• When recovered, a Hero enters the state of ALIVE.

If we have a new State or a new behavior, we will have to modify code in HeroContext.

Example output:

## HeroStateV2

Here we are applying the State Pattern with HeroContext and State

• create a State interface with all possible behaviors (actions).
• implement the State interface in concrete classes, each class has its own implementation for all bebaviors.
• HeroContext includes all different State and calls state.handle(). All behaviors handle() are delegated to State.

We can think of the State Pattern as an alternative to having a lot of if-else conditions in the context.

Using the State Pattern, we encapsulate what varies (behaviors) in State classes and usually have to create more classes in the design. The client HeroContext knows very little about the state object. The current state of the context changes across a set of state objects to reflect its internal state, and the behaviors of the context changes as well. When we call context.handle(), depending on the current state of the context, the behaviors vary.

Example output is the same as before.

## HeroStateV3

Here we have two new behaviors disappear, appear (in red) associated with a new state InvisibleState.

Using State Pattern, we can keep HeroContext mostly unchanged.

• When we have a new behavior, we can modify the State interface and implement this behavior in State classes.
• When we have a new State, we can easily create a new class implementing State interface and define its behaviors.

The state transition graph is shown below:

Example output:

## Real life use cases

1. Uber trip booking: State Machine Design pattern — Part 2: State Pattern vs. State Machine
2. E-commerce ordering, food ordering, and trip booking: Finite State Machines + Android + Kotlin = Good Times
3. Mobile app UI activity flow: State Machine Design pattern —Part 1: When, Why & How
4. Workflow engine (sequential pattern): WORKFLOW ENGINE VS. STATE MACHINE

This site uses Akismet to reduce spam. Learn how your comment data is processed.