State#
The state design pattern is used to manage different states of an object. This pattern comes under behavioral patterns. It allows an object to change its behavior when its internal state changes.
Overview#
In this pattern, a class (called Context) maintains a reference to one of the many instances of another class (called State). When the context requests the current state from the states, the states are able to perform certain operations. The context also allows the states to change their own internal state and possibly send notifications about these changes.
Java Implementation#
A vending machine example that dispenses snacks. We have three states: NoCoin, HasCoin, and Dispensing. Each state has its own behavior.
State Design Pattern#
// States
interface VendingMachineState {
void insertCoin();
void ejectCoin();
void selectSnack();
}
class NoCoin implements VendingMachineState {
@Override
public void insertCoin() {
System.out.println("Coin inserted. Now, you can select a snack.");
// Transition to HasCoin state
}
@Override
public void ejectCoin() {
throw new UnsupportedOperationException("No coin has been inserted");
}
@Override
public void selectSnack() {
throw new UnsupportedOperationException("No coin has been inserted");
}
}
class HasCoin implements VendingMachineState {
@Override
public void insertCoin() {
System.out.println("You already have a coin. You can't insert another one.");
}
@Override
public void ejectCoin() {
System.out.println("Coin ejected.");
// Transition to NoCoin state
}
@Override
public void selectSnack() {
System.out.println("Selecting a snack...");
// Transition to Dispensing state
}
}
class Dispensing implements VendingMachineState {
@Override
public void insertCoin() {
throw new UnsupportedOperationException("You are currently dispensing a snack");
}
@Override
public void ejectCoin() {
throw new UnsupportedOperationException("You are currently dispensing a snack");
}
@Override
public void selectSnack() {
System.out.println("Dispensing the snack...");
// Transition to NoCoin state
}
}
// Context (Vending Machine)
class VendingMachine {
private VendingMachineState state;
public VendingMachine() {
this.state = new NoCoin();
}
public void insertCoin() {
state.insertCoin();
}
public void ejectCoin() {
state.ejectCoin();
}
public void selectSnack() {
state.selectSnack();
}
}
// Usage
public class Main {
public static void main(String[] args) {
VendingMachine vendingMachine = new VendingMachine();
vendingMachine.insertCoin();
vendingMachine.selectSnack();
vendingMachine.ejectCoin();
vendingMachine.insertCoin();
vendingMachine.selectSnack();
}
}