Objects for States
Allow an object to alter its behavior when its internal state changes. The object will appear to change its class.
Real-world example
When observing a mammoth in its natural habitat it seems to change its behavior based on the situation. It may first appear calm, but over time when it detects a threat, it gets angry and dangerous to its surroundings.
In plain words
State pattern allows an object to change its behavior.
Wikipedia says
The state pattern is a behavioral software design pattern that allows an object to alter its behavior when its internal state changes. This pattern is close to the concept of finite-state machines. The state pattern can be interpreted as a strategy pattern, which is able to switch a strategy through invocations of methods defined in the pattern’s interface.
Programmatic Example
Here is the state interface and its concrete implementations.
1public interface State {
2
3 void onEnterState();
4
5 void observe();
6}
7
8@Slf4j
9public class PeacefulState implements State {
10
11 private final Mammoth mammoth;
12
13 public PeacefulState(Mammoth mammoth) {
14 this.mammoth = mammoth;
15 }
16
17 @Override
18 public void observe() {
19 LOGGER.info("{} is calm and peaceful.", mammoth);
20 }
21
22 @Override
23 public void onEnterState() {
24 LOGGER.info("{} calms down.", mammoth);
25 }
26}
27
28@Slf4j
29public class AngryState implements State {
30
31 private final Mammoth mammoth;
32
33 public AngryState(Mammoth mammoth) {
34 this.mammoth = mammoth;
35 }
36
37 @Override
38 public void observe() {
39 LOGGER.info("{} is furious!", mammoth);
40 }
41
42 @Override
43 public void onEnterState() {
44 LOGGER.info("{} gets angry!", mammoth);
45 }
46}
And here is the mammoth containing the state.
1public class Mammoth {
2
3 private State state;
4
5 public Mammoth() {
6 state = new PeacefulState(this);
7 }
8
9 public void timePasses() {
10 if (state.getClass().equals(PeacefulState.class)) {
11 changeStateTo(new AngryState(this));
12 } else {
13 changeStateTo(new PeacefulState(this));
14 }
15 }
16
17 private void changeStateTo(State newState) {
18 this.state = newState;
19 this.state.onEnterState();
20 }
21
22 @Override
23 public String toString() {
24 return "The mammoth";
25 }
26
27 public void observe() {
28 this.state.observe();
29 }
30}
Here is the full example of how the mammoth behaves over time.
1 var mammoth = new Mammoth();
2 mammoth.observe();
3 mammoth.timePasses();
4 mammoth.observe();
5 mammoth.timePasses();
6 mammoth.observe();
Program output:
1 The mammoth gets angry!
2 The mammoth is furious!
3 The mammoth calms down.
4 The mammoth is calm and peaceful.
Use the State pattern in either of the following cases