Skip to content

Commit

Permalink
#590 add explanation for State
Browse files Browse the repository at this point in the history
  • Loading branch information
iluwatar committed Jul 20, 2020
1 parent b907a2a commit ab4e53a
Showing 1 changed file with 120 additions and 2 deletions.
122 changes: 120 additions & 2 deletions state/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,126 @@ tags:
Objects for States

## Intent
Allow an object to alter its behavior when its internal state
changes. The object will appear to change its class.
Allow an object to alter its behavior when its internal state changes. The object will appear to change its class.

## Explanation
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.

```java
public interface State {

void onEnterState();

void observe();
}

public class PeacefulState implements State {

private static final Logger LOGGER = LoggerFactory.getLogger(PeacefulState.class);

private Mammoth mammoth;

public PeacefulState(Mammoth mammoth) {
this.mammoth = mammoth;
}

@Override
public void observe() {
LOGGER.info("{} is calm and peaceful.", mammoth);
}

@Override
public void onEnterState() {
LOGGER.info("{} calms down.", mammoth);
}
}

public class AngryState implements State {

private static final Logger LOGGER = LoggerFactory.getLogger(AngryState.class);

private Mammoth mammoth;

public AngryState(Mammoth mammoth) {
this.mammoth = mammoth;
}

@Override
public void observe() {
LOGGER.info("{} is furious!", mammoth);
}

@Override
public void onEnterState() {
LOGGER.info("{} gets angry!", mammoth);
}
}
```

And here is the mammoth containing the state.

```java
public class Mammoth {

private State state;

public Mammoth() {
state = new PeacefulState(this);
}

public void timePasses() {
if (state.getClass().equals(PeacefulState.class)) {
changeStateTo(new AngryState(this));
} else {
changeStateTo(new PeacefulState(this));
}
}

private void changeStateTo(State newState) {
this.state = newState;
this.state.onEnterState();
}

@Override
public String toString() {
return "The mammoth";
}

public void observe() {
this.state.observe();
}
}
```

And here is the full example how the mammoth behaves over time.

```java
var mammoth = new Mammoth();
mammoth.observe();
mammoth.timePasses();
mammoth.observe();
mammoth.timePasses();
mammoth.observe();

// The mammoth gets angry!
// The mammoth is furious!
// The mammoth calms down.
// The mammoth is calm and peaceful.
```

## Class diagram
![alt text](./etc/state_1.png "State")
Expand Down

0 comments on commit ab4e53a

Please sign in to comment.