> For the complete documentation index, see [llms.txt](https://jrp.gitbook.io/notes/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://jrp.gitbook.io/notes/design-pattern/behavioural-state-pattern.md).

# Behavioural - State Pattern

<div data-with-frame="true"><figure><img src="/files/ABZXG4tKDLZS0vFY5kDo" alt=""><figcaption></figcaption></figure></div>

We  act differently depending on your mood or situation:

* If we’re at office, we are focused and working.
* If we're with friends, we're chatting and having fun.
* If we're playing sports, we're energetic and competitive.

It’s the same idea: **our behavior adapts based on our current state.**&#x20;

The State Pattern helps software do that, switching “**rules**” automatically when things change.

Think of it like the snack machine at office!

* The vending machine can be in **two states**:
  * **Waiting for a coin** (TakeCoinState)
  * **Releasing a product** (ReleaseProductState)
* The vending machine changes its behavior based on its state:
  * In coin state: asks for money.
  * In release state: gives you your chips or drink
* The machine is an object that can switch between these states.
  * Each state has its own simple logic.
  * When its state changes, its behavior changes—just like the real machine

So, the state pattern let you easy to switch and add new states later!

### Low Level Design

<figure><img src="/files/SlxG5kealDpiGb0nuo9y" alt=""><figcaption></figcaption></figure>

### Implementation

#### Interface

```java
public interface VendingMachineState {
	void processRequest();
}
```

#### Context

```java
public class VendingMachineContext {
	VendingMachineState state;

	public VendingMachineState getState() {
		return state;
	}

	public void setState(VendingMachineState state) {
		this.state = state;
	}

	void doAction() {
		state.processRequest();
	}
}
```

#### 2 States

```java
public class TakeCoinState implements VendingMachineState {
	@Override
	public void processRequest() {
		System.out.println("Insert coin");
	}
}
```

```java
public class ReleaseProductState implements VendingMachineState {
	@Override
	public void processRequest() {
		System.out.println("Releasing product");
	}
}
```

#### Customer

```java
public class Customer {

	public static void main(String[] args) {
		VendingMachineContext context = new VendingMachineContext();

		VendingMachineState state1 = new TakeCoinState();
		//Changing the state
		context.setState(state1);
		//behaviour will be changed
		context.doAction();

		VendingMachineState state2 = new ReleaseProductState();
		//Changing the state
		context.setState(state2);
		//behaviour will be changed
		context.doAction();
	}
}
```

### Benefits

* If you anticipate adding new states in the future, the State pattern facilitates this by allowing you to create new state classes without affecting existing ones.
* When conditional statements (if-else or switch-case) become extensive and complex within your object, the State pattern helps organize and separate state-specific behavior into individual classes, enhancing readability and maintainability.

Example in JDK

A `Thread` has **multiple states**:

```java
public enum Thread.State {
    NEW,
    RUNNABLE,
    BLOCKED,
    WAITING,
    TIMED_WAITING,
    TERMINATED
}

```

The **same method** on `Thread` behaves **differently** depending on the current state.

| Operation     | Behavior depends on state                                                   |
| ------------- | --------------------------------------------------------------------------- |
| `start()`     | only valid in **NEW** state; throws `IllegalThreadStateException` otherwise |
| `run()`       | only executed in **RUNNABLE** state                                         |
| `interrupt()` | behavior depends on whether thread is **WAITING**, **BLOCKED**, or RUNNING  |
| `join()`      | blocks until state becomes **TERMINATED**                                   |

```java
public class ThreadStateExample {
    public static void main(String[] args) throws InterruptedException {

        Thread t = new Thread(() -> {
            try { Thread.sleep(200); } catch (Exception ignored) {}
        });

        System.out.println(t.getState()); // NEW

        t.start();
        System.out.println(t.getState()); // RUNNABLE (or TIMED_WAITING soon)

        Thread.sleep(50);
        System.out.println(t.getState()); // TIMED_WAITING (while sleeping)

        t.join();
        System.out.println(t.getState()); // TERMINATED
    }
}

```

Output (varies)

```
NEW
RUNNABLE
TIMED_WAITING
TERMINATED

```

| Feature                                     | How Thread shows it                           |
| ------------------------------------------- | --------------------------------------------- |
| Object has internal state                   | `Thread.State` enum                           |
| Methods behave differently based on state   | `start()`, `join()`, `interrupt()`, etc.      |
| State transitions happen during execution   | NEW → RUNNABLE → BLOCKED/WAITING → TERMINATED |
| Client does not manually manage transitions | JVM and scheduler control it                  |
