State Pattern

Pros

  • Allows changing of an object's behavior depending on its state at run-time
  • Removes the need for repetitive conditionals by moving state behavior into their own class

Cons

  • Increases complexity which may be a bad thing if there are only a few simple state changes

Example Explanation

GachaMachine

IGachaState - interface that encapsulates state behavior of the GachaMachine

GachaGivingPrize/GachaWithCoin/GachaNoCoin - concrete implementations of IGachaState

class Main {
  public static void main(String[] args) {
    GachaMachine machine = new GachaMachine();
    machine.displayState(); //Current State: NoCoinState
    machine.givePrize(); //No coin inserted.
    machine.pressButton(); //No coin inserted.
    machine.insertCoin(); //Coin inserted..
    //--changing state--
    machine.displayState(); //Current State: WithCoinState
    machine.insertCoin(); //Coin already inserted.
    machine.givePrize(); //Press button for prize.
    machine.pressButton(); //Button pressed..
    //--changing state--
    machine.displayState(); //Current State: GivingPrizeState
    machine.insertCoin(); //Coin already inserted.
    machine.pressButton(); //Button already pressed.
    machine.givePrize(); //Giving prize..
    //--changing state--
    machine.displayState(); //Current State: NoCoinState
  }
}
interface IGachaState{
  public void insertCoin();
  public void pressButton();
  public void givePrize();
}

class GachaNoCoin implements IGachaState{
  private GachaMachine machine;
  public GachaNoCoin(GachaMachine machine){
    this.machine = machine;
  }

  @Override
  public void insertCoin(){
    System.out.println("Coin inserted..");
    machine.setState( machine.getWithCoinState() );
  }
  @Override
  public void pressButton(){
    System.out.println("No coin inserted.");
  }
  @Override
  public void givePrize(){
    System.out.println("No coin inserted.");
  }
  @Override
  public String toString(){ return "NoCoinState"; }
}

class GachaWithCoin implements IGachaState{
  private GachaMachine machine;
  public GachaWithCoin(GachaMachine machine){
    this.machine = machine;
  }

  @Override
  public void insertCoin(){
    System.out.println("Coin already inserted.");
  }
  @Override
  public void pressButton(){
    System.out.println("Button pressed..");
    machine.setState( machine.getGivingPrizeState() );
  }
  @Override
  public void givePrize(){
    System.out.println("Press button for prize.");
  }
  @Override
  public String toString(){ return "WithCoinState"; }
}

class GachaGivingPrize implements IGachaState{
  private GachaMachine machine;
  public GachaGivingPrize(GachaMachine machine){
    this.machine = machine;
  }

  @Override
  public void insertCoin(){
    System.out.println("Coin already inserted.");
  }
  @Override
  public void pressButton(){
    System.out.println("Button already pressed.");
  }
  @Override
  public void givePrize(){
    System.out.println("Giving prize..");
    machine.setState( machine.getNoCoinState() );
  }
  @Override
  public String toString(){ return "GivingPrizeState"; }
}

class GachaMachine implements IGachaState{
  private IGachaState noCoinState;
  private IGachaState withCoinState;
  private IGachaState givingPrizeState;
  private IGachaState state;

  public GachaMachine(){
    this.noCoinState = new GachaNoCoin(this);
    this.withCoinState = new GachaWithCoin(this);
    this.givingPrizeState = new GachaGivingPrize(this);
    this.state = noCoinState;
  }
  public void setState(IGachaState state){ 
    this.state = state; 
    System.out.println("--changing state--");
  }
  @Override
  public void insertCoin(){
    state.insertCoin();
  }
  @Override
  public void pressButton(){
    state.pressButton();
  }
  @Override
  public void givePrize(){
      state.givePrize();
  }
  public void displayState(){ System.out.println("Current State: "+state.toString()); };
  public IGachaState getNoCoinState(){ return noCoinState; }
  public IGachaState getWithCoinState(){ return withCoinState; }
  public IGachaState getGivingPrizeState(){ return givingPrizeState; }
}

Extra Resources

https://springframework.guru/gang-of-four-design-patterns/state-pattern/

results matching ""

    No results matching ""