State (State mode)

State is a behavioral pattern.

Intent: Allows an object to change its behavior when its internal state changes. Object appears to have modified its class.

Simply put, replace “a large class + a bunch of if else” with “a bunch of small classes”. A bunch of little classes is a bunch of states, and using a bunch of states instead of if else is much easier to expand and maintain.

For example,

If you don’t understand the above description, it doesn’t matter. Design patterns need to be used in daily work. Examples will help you understand better.

Team interface person

The team is composed of many students, but there is an interface TL, who may talk about requirements with the product manager, planning with other TL, and HR with HR. In short, there are many things to do. Obviously, one person is too busy to do. TL by distributed tasks to each student in the team, and not let them direct contact with product managers, other TL, HR, then the efficiency of the TL will be quite high, because each student is responsible for only a specific piece of business, called on the TL in different time of different students, let them to solve the problem they are responsible for the professional field, Therefore, from the outside, the TL team has a wide range of capabilities, while from the inside, each person is responsible for a single thing.

Desk lamp button

We often see only a button desk lamp, but can adjust the brightness through the button, is probably the following cycle “off -> weak light -> bright -> strong light -> off”, so each time after pressing the button, to jump to what state, in fact, and the current state. We can solve this problem with if else, or we can solve it with state mode.

To solve the problem with the state pattern, these four states are encapsulated into four classes, each of which performs the state to jump to after pressing the button, so that a new pattern can be added in the future by changing part of the classes.

Database connector

The state of the connector is obviously very different before and after the database connection, and if we use only one class to describe the database connector, we will have to write a lot of internal branch statements to determine the state. Is there a better plan at this point? State model tells us that you can create multiple different states, such as connection, connection, connection before three states after class, will replace with different subclasses within different times, they all inherit the same parent class, so don’t look outside need to perceive the internal change of state, the internal and can undertake state resolution, for better maintenance.

Intention to explain

Intent: Allows an object to change its behavior when its internal state changes. Object appears to have modified its class.

The key is the understanding of “internal state,” meaning that state changes are triggered from within the object, not from the outside, so the outside doesn’t care if the object is using state mode. In the example of the database connector, whether the class is stacked with if else or with state mode, The state pattern is essentially a cohesive design pattern, without interfering with the stable API it provides externally.

chart

  • State: indicates the status interface.
  • ConcreteState: ConcreteState, both inherited from State, analogous to the strong light and weak light State of a table lamp.

The code example

The following example is written in typescript.

// Define the status interface
interface State {
  // Simulate lamp lighting
  show: () = > string
}

class Light1 implements State {
  constructor(context: Context) {
    this.context = context
  }

  show() {
    return 'off'
  }

  // Press the button
  public click() {
    this.context.setState(new Light2(this.context))
  }
}

class Light2 implements State {
  constructor(context: Context) {
    this.context = context
  }

  show() {
    return 'weak light'
  }

  // Press the button
  public click() {
    this.context.setState(new Light3(this.context))
  }
}

class Light3 implements State {
  constructor(context: Context) {
    this.context = context
  }

  show() {
    return 'bright'
  }

  // Press the button
  public click() {
    this.context.setState(new Light4(this.context))
  }
}

class Light4 implements State {
  constructor(context: Context) {
    this.context = context
  }

  show() {
    return 'light'
  }

  // Press the button
  public click() {
    this.context.setState(new Light1(this.context))
  }
}

/ / desk lamp
public class Lamp {
  // Current status
  private currentState = new Light1(this)

  protected setState(state: State) {
    this.currentState = state
  }

  // Press the button
  public click() {
    this.getState().click()
  }
}

const lamp = new Lamp() / / close
lamp.click() / / weak light
lamp.click() / / bright
lamp.click() / / light
lamp.click() / / close
Copy the code

There are a number of ways to do this. You don’t have to be formal. Basically, you just have to make sure that multiple classes implement different states, and each class implements the next state.

disadvantages

Use if else when you should, don’t use state mode whenever you have an if else, that’s just silly reading. It is important to determine if the states vary significantly and if using state mode is more maintainable than if else.

conclusion

In the right circumstances, state patterns make code more open and closed, and logic more streamlined, focused, and maintainable when each class is maintained independently.

The discussion address is: Close reading design Pattern-State Mode · Issue #303 · DT-fe /weekly

If you’d like to participate in the discussion, pleaseClick here to, with a new theme every week, released on weekends or Mondays. Front end Intensive Reading – Helps you filter the right content.

Pay attention to the front end of intensive reading wechat public account

Copyright Notice: Freely reproduced – Non-commercial – Non-derivative – Remain signed (Creative Commons 3.0 License)