State Patterns in Design Patterns Series

Keywords: REST

Brief Book Address: http://www.jianshu.com/p/67ad1915fd62
Nugget address: https://juejin.im/post/59c4c2c6f265da066875f9f8

"Welcome to watch the vulgar"Little Y Hall"on time. Hello, I'm Little Y, a programmed ape with sexy hair and talent. Many small partners should have the same feeling: the hero's heroic single bombing of the building is common in anti-Japanese films and television programs. The charm of the plot lies in the hero carrying explosive bags, placing, leaving, igniting each link in the process of interlocking, exciting and emotional fluctuations. If someone asks Xiao Y at this moment, what will he think of when he sees this kind of plot movie? Isn't that nonsense? Of course, the theme of "Little Y Lecture" this time is state mode!!!!! __________

I. The Concept of State Patterns

Definition of state pattern

Allowing an object to change its behavior when its internal state changes, the object looks like it has changed its class.

Usage scenarios

  • Behavior changes with state.
  • If you need to use a lot of conditions, branch judgment.

Role introduction

  • State abstract state role

    Interfaces or abstract classes are responsible for object state definition and encapsulate environment roles for state switching.

  • ConcreteState Specific Status Roles

    Specific state has two main responsibilities: one is to deal with the state of things, and the other is how to transition from the state to other states.

  • Context environment role

    Define the interface the client needs, and be responsible for switching the specific state.

II. Small Y Explosive Building

  Platoon Leader: The instructions given above are to blow up the ghost's artillery building at all costs. Can you all accomplish the task?
  Soldiers: Swear to death to complete the task.
  Platoon Leader: Very good, little Y. Take the explosive bag, put the explosive bag under the gun tower, and then leave immediately. Then we'll blow it up. Don't worry, we'll cover you.
  Little Y:....

1. UML Diagram of Process State of Explosive Gun Building

2. Implementing tasks

First, define what to do at each stage of the explosion building.

public abstract class LinkState{
   protected Context context;
   public void setContext(Context  context){
      this.context = context;
   }
   //Bombing cartridge
   public abstract void carry();
   //Place explosive bags
   public abstract void put();
   //make off with money
   public abstract void goaway();
   //Ignition of explosive cartridge
   public abstract void ignite();

}

(2) Running with explosives to the bottom of the gun building

public class CarryingState extends LinkState{
  @Override
  public void carry() {
    System.out.println("Small Y:Reporting platoon leader, I've run to the bottom of the gun tower");
  }

  @Override
  public void put() {
    super.context.setLinkState(Context.puttingState);
    super.context.getLinkState().put();
  }
  @Override
  public void goaway() {
   System.out.println("Small Y:No explosives were placed and evacuation failed.");
  }
  @Override
  public void ignite() {
     System.out.println("Small Y:The explosive has not been placed successfully, the detonation failed.");
  }
}

(3) Place the explosive under the gun building.

public class PuttingState extends LinkState{
   @Override
  public void carry() {
    System.out.println("Small Y:It's still in the enemy's area. It's impossible to carry any more explosive bags.");
  }

  @Override
  public void put() {
    System.out.println("Small Y:It's dangerous. Successful in placing explosive bags.");
  }
  @Override
  public void goaway() {
    super.context.setLinkState(Context.goawayingState);
    super.context.getLinkState().goaway();
  }
  @Override
  public void ignite() {
     System.out.println("Small Y:No explosives can be detonated without escaping from enemy areas.");
  }
}

Fourthly, if the explosives are placed properly, they will not rush off and wait for the explosives to explode.

public class GoAwayingState extends LinkState{
   @Override
  public void carry() {
    System.out.println("Small Y:They have escaped and can no longer carry explosive bags.");
  }

  @Override
  public void put() {
    System.out.println("Small Y:It has escaped and cannot be placed with explosive packs.");
  }
  @Override
  public void goaway() {
     System.out.println("Small Y:call~~,Finally, I found my life back.");
  }
  @Override
  public void ignite() {
     super.context.setLinkState(Context.ignitingState);
    super.context.getLinkState().ignite();
  }
}

Xiao Y succeeded in escaping and detonating immediately.

public class IgnitingState extends LinkState{
   @Override
  public void carry() {
    System.out.println("The gun building didn't fall down completely. It's small. Y Keep carrying explosives");
    super.context.setLinkState(Context.carryingState);
    super.context.getLinkState().carry();
  }

  @Override
  public void put() {
    System.out.println("Small Y:The explosive has been detonated without the need to place the explosive bag.");
  }
  @Override
  public void goaway() {
     System.out.println("Small Y:The explosive has detonated and has been evacuated.");
  }
  @Override
  public void ignite() {
      System.out.println("Small Y:The bombing was completed, and a salary increase was prepared for promotion.");
  }
}

Responsible for switching the state of each stage of the explosion building

public class Context {
  //Define all States of explosive building
  public final static CarryingState carryingState = new CarryingState();
  public final static PuttingState puttingState = new PuttingState();
  public final static GoAwayingState goawayingState = new GoAwayingState();
  public final static IgnitingState ignitingState = new IgnitingState();

  //Set the current state
  private LinkState linkState;

  public LinkState getLinkState() {
    return linkState;
  }

  public void setLinkState(LinkState linkState) {
     this.linkState= linkState;
     //Notify the current status to the implementation classes
     this.linkState.setContext(this);
  }

  public void carry(){
    this.linkState.carry();
  }

  public void put(){
    this.linkState.put();
  }

 public void goaway(){
    this.linkState.goaway();
  }

 public void ignite(){
    this.linkState.ignite();
  }

 }

The execution of the bombing building

public class Client {
   public static void main(String[] args) {
       Context context = new Context();
       context.setLinkState(Context.carryingState);
       context.carry();
       context.ignite();
       context.put();
       context.goaway();
       context.ignite();
    }
}  

The output is as follows:

Xiao Y: Report platoon leader, I have run to the bottom of the gun building.
Small Y: No explosive has been placed successfully, and the detonation failed.
(3) Small Y: Good and dangerous. Successful placement of explosive bags
 (4) Xiao Y: Huo ~, finally pick up a small life.
(5) Xiao Y: The explosion was completed and the salary was raised for promotion.

Summary and analysis

(1) A LinkState abstract class is defined and a Context variable is declared, which is an encapsulated class that concatenates various states. The purpose of encapsulation is obvious, that is, the change of the internal state of the link state object is not known by the calling class, which conforms to Dimiter's law.

(2) Context environment roles have two unwritten constraints: one is that several state objects declare several static constants; the other is that all acts defined by state Abstract roles are executed in a delegated manner.

(3) What each specific status role needs to do is to deal with the corresponding actions in the state. If the actions do not belong to the state processing, it will switch the state and entrust the behavior to the State responsible for the behavior.

(4) Each state can be switched from one another.

Advantages of state mode

  • It embodies the principle of opening and closing and the principle of single responsibility. Each state is a subclass. If you want to add states, you need to add subclasses. If you want to modify states, you can only modify one subclass.
  • It conforms to Dimiter's law.
  • The encapsulation is very good.
  • The structure is clear, avoiding too many switch es. case or if... The use of else statement avoids the complexity of the program and improves the maintainability.

Xiao Y bravely bombed the enemy's artillery building, hoping to enjoy the rest of his life, and was awarded "full-time bomber" by his superiors.

Wechat Public Number:

Posted by adamlacombe on Wed, 22 May 2019 16:49:02 -0700