[Design Pattern Series 19] Analysis of the principle of state mode and its difference from strategy mode and chain of responsibility mode

Design pattern series overview

Design Patterns Air ticket
Three factory models Boarding entrance
Strategy mode Boarding entrance
Delegation mode Boarding entrance
Template method pattern Boarding entrance
Observer mode Boarding entrance
Singleton mode Boarding entrance
Prototype mode Boarding entrance
Agency model Boarding entrance
Decorator mode Boarding entrance
Adapter mode Boarding entrance
Builder mode Boarding entrance
Chain of Responsibility Model Boarding entrance
Flyweight model Boarding entrance
Combination mode Boarding entrance
Facade pattern Boarding entrance
Bridge mode Boarding entrance
Intermediary model Boarding entrance
Iterator mode Boarding entrance
State mode Boarding entrance
Interpreter mode Boarding entrance
Memo mode Boarding entrance
Command mode Boarding entrance
Visitor mode Boarding entrance
Summary of 7 principles and design patterns of software design Boarding entrance

Preface

The state is quite familiar to us developers. In normal development, the state of the object is always inseparable. For example, our review process is a process of continuous state flow, and the order process is also a process of continuous state flow, and state mode It is to better solve the business processing logic in our state circulation process.

What is state mode

State Pattern, also known as State Machine Pattern, allows an object to change its behavior while its internal state changes, making it look like a modified class.

The behavior of the class in the state pattern is determined by the state, and different states have different behaviors. The intent of the state pattern is to make an object change its behavior along with it.

The core of the state pattern is to bind a behavior to each state.

Okay, the time to pretend is here again: Talk is cheap, Show you the code , let’s look at a very simple example first.

State pattern example

Below we write a simple example based on the flow of order status. We assume that the order has only three statuses: to be paid, to be received, and received (completed).

1. First, create an abstract state class, which needs to define all the behaviors of all states:

package com.zwx.design.pattern.state;

public abstract class AbstractOrderState {
    
    
    protected OrderContext orderContext;

    public AbstractOrderState(OrderContext orderContext) {
    
    
        this.orderContext = orderContext;
    }

    public abstract void payOrder();

    public abstract void deliver();

    public abstract void receiveGoods();
}

Note that it integrates an OrderContext object, which is used to switch the state.

2. Because there are three states, we create three concrete state classes to implement abstract state classes:

  • Pending payment status category:
package com.zwx.design.pattern.state;

public class WaitPaidOrderState extends AbstractOrderState {
    
    
    public WaitPaidOrderState(OrderContext orderContext) {
    
    
        super(orderContext);
    }

    @Override
    public void payOrder() {
    
    //相当于待支付的状态绑定了支付行为
        System.out.println("支付成功");
        this.orderContext.setState(this.orderContext.waitDeliver);//切换状态
    }

    @Override
    public void deliver() {
    
    
        System.out.println("对不起,请先付钱");
    }

    @Override
    public void receiveGoods() {
    
    
        System.out.println("对不起,请先付钱");
    }
}
  • Pending delivery status class:
package com.zwx.design.pattern.state;

public class WaitDeliverOrderState extends AbstractOrderState {
    
    
    public WaitDeliverOrderState(OrderContext orderContext) {
    
    
        super(orderContext);
    }

    @Override
    public void payOrder() {
    
    
        System.out.println("你已经付过钱了");
    }

    @Override
    public void deliver() {
    
    
        System.out.println("商品已发货并送达目的地");
        this.orderContext.setState(this.orderContext.receiveGoods);//切换状态
    }

    @Override
    public void receiveGoods() {
    
    
        System.out.println("请稍等,商品即将发货");
    }
}
  • Received status class:
package com.zwx.design.pattern.state;

public class ReceiveGoodsOrderState extends AbstractOrderState{
    
    
    public ReceiveGoodsOrderState(OrderContext orderContext) {
    
    
        super(orderContext);
    }

    @Override
    public void payOrder() {
    
    
        System.out.println("您已经付过钱啦,不要重复付钱哦");
    }

    @Override
    public void deliver() {
    
    
        System.out.println("商品已发货并送达,请不要重复发货");
    }

    @Override
    public void receiveGoods() {
    
    
        System.out.println("用户已收到商品,此次交易结束");
    }
}

We can see that each state is bound to a behavior (and can also support multiple binding), and after the corresponding behavior is processed, it will flow to the next state, and the behavior that does not belong to the current state will be made accordingly. Response.

3. Create a state context environment class to be responsible for switching between specific states:

package com.zwx.design.pattern.state;

/**
 * @author zwx
 * @version 1.0
 * @date 2020/10/5
 * @since jdk1.8
 */
public class OrderContext {
    
    
    AbstractOrderState waitPaid;
    AbstractOrderState waitDeliver;
    AbstractOrderState receiveGoods;

    AbstractOrderState currState;//当前状态

    public OrderContext() {
    
    
        this.waitPaid = new WaitPaidOrderState(this);
        this.waitDeliver = new WaitDeliverOrderState(this);
        this.receiveGoods = new ReceiveGoodsOrderState(this);
        currState = waitPaid;
    }

    void setState(AbstractOrderState state){
    
    
        this.currState = state;
    }

    public void payOrder(){
    
    
        currState.payOrder();
    }


    public void deliver(){
    
    
        currState.deliver();
    }

    public void receiveGoods(){
    
    
        currState.receiveGoods();
    }
}

As you can see, this class also has a shadow of the delegation mode. Different behaviors are delegated to the corresponding objects for processing, and they are only responsible for state switching.

4. Finally, create a new test class for testing:

package com.zwx.design.pattern.state;

public class TestState {
    
    
    public static void main(String[] args) {
    
    
        OrderContext orderContext = new OrderContext();
        orderContext.payOrder();
        orderContext.deliver();
        orderContext.receiveGoods();
    }
}

The output result is:

支付成功
商品已发货并送达目的地
用户已收到商品,此次交易结束

State mode role

From the above example, we can conclude that there are three main roles in the state model:

  • Context: defines the interface required by the client, maintains an instance of the current state internally, and is responsible for the switching of specific states.
  • Abstract state role (State): Define the corresponding behavior in each state, there can be one or more behaviors.
  • Concrete state role (ConcreteState): concretely realize the behavior corresponding to the state, and realize the state switching when needed.

State mode and chain of responsibility mode

It seems that the implementation of this state mode is similar to the chain of responsibility mode , which is handled by one chain. It can be said that the two modes can replace each other in a certain scenario, but the two modes are also essentially different.

  • State mode:
    The next node of the state mode is already understood by each state object, and the state transfer is carried out internally, and the client cannot decide.

  • The object on the "link" of the chain of responsibility model does not know who the next node processor is, but is determined by the client itself.

State mode and strategy mode

Both state mode and strategy mode can be used to eliminate a large number of if/else scenarios, but there are essential differences. Each strategy in the strategy mode is independent and interchangeable. Any choice of one strategy can meet the demand, and the client makes the choice. The state mode client can only select the initial node, and it will automatically flow in the subsequent. Each state is a whole, and there is no state that can be replaced with each other.

State mode application scenarios

When the conditional expression that controls the state of an object is too complicated, you can consider using the state mode. By transferring the judgment logic of the state to a series of classes representing different states, you can simplify the complex logic and make the object The behavior of depends on its state, and will change its behavior as the state changes.
State mode is mainly used in the following scenarios:

  • 1. When the behavior of the object needs to be changed as the state changes.
  • 2. When we need to write a large amount of if/else logic according to the state in an operation

Advantages and disadvantages of state mode

advantage:

  • 1. By setting each state as an independent object, a large number of if/else branches in the code are eliminated, making the code more concise and easier to maintain.
  • 2. Different states are represented by different classes, which makes the state switching more intuitive than when it is represented by numbers or strings, and the purpose of the conversion is clearer.
  • 3. The responsibilities of each status class are single and clear, and easy to extend.

Disadvantage

  • 1. Too many states will cause class expansion (in fact, this is also a common problem in most design patterns).
  • 2. The structure and implementation of the state mode are relatively complex, which can easily cause code confusion.
  • 3. The state class that supports state switching violates the opening and closing principle, because once the state is modified or the state needs to be added in the middle, the corresponding source code needs to be modified, otherwise a state switching error will occur.

to sum up

This article mainly introduces the definition of the state pattern, and implements a simple state pattern through a simple example. Finally, the state pattern and the responsibility chain pattern are compared and analyzed, and the difference between the state pattern and the responsibility chain pattern is clarified.

Please pay attention to me and learn and progress with the lone wolf .

Guess you like

Origin blog.csdn.net/zwx900102/article/details/109202186