The year 2020 has entered the countdown, we set up the flag is completed? 2020 is not easy to “rat”, I hope that 2021 will be “ox” to change the world.

Introduction to the

State pattern is a kind of behavioral design pattern. The idea is to change the behavior of an object when its internal state changes. There is a one-to-one correspondence between state and behavior.

This mode is used when the behavior of an object depends on its state and its behavior switches as its state changes.

State pattern UML class diagram

Class diagram to explain

State: Abstract State interface (can also be defined as abstract class), which encapsulates the behavior of all states.

ConcreteStateA/B: Concrete state class. This class implements an abstract state interface, implements methods defined in the interface based on its corresponding state, and specifies how to transition to the next state. Context: An environment role that is responsible for switching states and holds an instance of State that represents the current State of the environment.

Case on

Case: Realize the function of self-service vending machine through state mode.

State interface

public interface State {
  // Select goods
  void choose(a);
  / / payment
  boolean payment(a);
  // Distribute goods
  void dispenseCommodity(a);
}
Copy the code

Pick the item status category

public class ChooseGoods implements State {

  VendingMachine machine;

  public ChooseGoods(VendingMachine machine) {
    this.machine = machine;
  }

  @Override
  public void choose(a) {
    if (machine.getCount() > 0) {
      System.out.println("Goods selected successfully, please pay in time!");
      machine.setState(machine.getPaymentState());
    } else {
      System.out.println("I'm sorry, it's sold out!"); machine.setState(machine.getEmptyState()); }}@Override
  public boolean payment(a) {
    System.out.println("Please choose your goods first!");
    return false;
  }

  @Override
  public void dispenseCommodity(a) {
    System.out.println("Please choose your goods first!"); }}Copy the code

Payment status class

public class PaymentState implements State {

  VendingMachine machine;

  public PaymentState(VendingMachine machine) {
    this.machine = machine;
  }

  @Override
  public void choose(a) {
    System.out.println("Please do not re-select the product after it has been selected.");
  }

  @Override
  public boolean payment(a) {
    Random random = new Random();
    int num = random.nextInt(10);
    if(num % 2= =0){
      System.out.println("Payment successful!");
      machine.setState(machine.getDispenseCommodityState());
      return true;
    }
    System.out.println("Payment failed, please pay again!");
    return false;
  }

  @Override
  public void dispenseCommodity(a) {
    System.out.println("Please complete payment first!"); }}Copy the code

Goods are sold out

public class EmptyState implements State {

  VendingMachine machine;

  public EmptyState(VendingMachine machine) {
    this.machine = machine;
  }

  @Override
  public void choose(a) {
    System.out.println("I'm sorry it's sold out!");
  }

  @Override
  public boolean payment(a) {
    System.out.println("I'm sorry it's sold out!");
    return false;
  }

  @Override
  public void dispenseCommodity(a) {
    System.out.println("I'm sorry it's sold out!"); }}Copy the code

Distribute the commodity status class

public class DispenseCommodityState implements State {

  VendingMachine machine;

  public DispenseCommodityState(VendingMachine machine) {
    this.machine = machine;
  }

  @Override
  public void choose(a) {
    System.out.println("Please pick up your goods in time!");
  }

  @Override
  public boolean payment(a) {
    System.out.println("Please pick up your goods in time!");
    return false;
  }

  @Override
  public void dispenseCommodity(a) {
    System.out.println("Please pick up your goods in time!"); machine.setState(machine.getChooseGoods()); }}Copy the code

Vending machine => Context role

public class VendingMachine {
  // Indicates the current status
  private State state = null;
  // Quantity of goods
  private int count = 0;
  private State chooseGoods = new ChooseGoods(this);
  private State paymentState = new PaymentState(this);
  private State dispenseCommodityState = new DispenseCommodityState(this);
  private State emptyState = new EmptyState(this);

  public VendingMachine(int count) {
    this.count = count;
    this.state = this.getChooseGoods();
  }

  // Buy goods
  public void purchase(a) {
    // Select goods
    state.choose();
    // The payment was successful
    if (state.payment()) {
      // Distribute goodsstate.dispenseCommodity(); }}// Get the item and subtract the item by one
  public int getCount(a) {
    return count--;
  }
  
  // Get and set methods...
}
Copy the code

Client test classes

public class Client {

  public static void main(String[] args) {
    VendingMachine machine = new VendingMachine(1);
    for (int i = 1; i < 4; i++) {
      System.out.println("The first" + i + "Second purchase."); machine.purchase(); }}}Copy the code

The execution result

conclusion

1. State mode encapsulates the behavior of each state into a class, greatly improving the readability of code. And through this design can also eliminate redundant if-else statements, convenient code maintenance.

2, the state mode conforms to the “open and close principle”, easy to add and delete the state.

3. Everything has pros and cons, and state patterns are no exception. The most obvious problem is that there is a class for each state, and when there are too many states, there are too many classes, which increases maintenance costs.

4. Application Scenarios: When a requirement has many states and transitions between states, different states also correspond to different behaviors, the “state pattern” can be considered.

This is the end of today’s sharing, if you feel that the article written by “rookie” is still good, remember to like, forward and pay attention to yo! Your support is what keeps me going. Article where to write problems also hope that you can point out, I will be modestly taught.