Java fresh business platform - an order module state machine architecture

Java fresh business platform - an order module state machine architecture

 

Description: In the Java platform in the fresh state electricity supplier orders transfer of business

       We know that there are a variety of state orders: temporary orders, orders have to be paid, pending receipt until the evaluation has been completed, and so in return. Are each state and state prior to twisting, torsion about the operating state before the execution.

An example illustrates

For example a process: The user added items to their shopping cart in the background to generate a so-called "provisional list", the order has not actually officially generated because the user still does not click orders. Only when a single user, the "provisional list" can be transformed into a "order to be paid." So this process: only one in the "provisional list" of state orders for the next single operation, to get a status of "pending payment" order. That is - a + a proper pre-state operation, in order to reverse the status of the order. In this process, if it is hard-coded, then we need a series of if ... else statement to check the current status of orders, perform operations and the status of these two combinations should be obtained by a transfer of value. If the order flow is very complicated, write out the logic will be very complicated, and readability is very low. Maintenance is a late pit.

Two state design pattern and order status Circulation

Deal with this problem, we can use a state machine design pattern to handle. Corresponds to practice, is a state machine.

Specific details about the state machine design patterns can be self Baidu. Here can be summed with a simple words: the internal state of the object varies with the external conditions performed. And then mapped onto the transfer order status: the status of the order, in combination with the current state of orders and changes the current operation is performed.

Abstract design with three pre-coding

 
 

Illustrates a simulated flow state in process order. Starting a temporary order, whenever an order is a known state, to get the order to change the state, we need to perform the corresponding operations.

From a state machine point of view, we first deal with a variety of information and abstract

3.1 Code abstract

The preparation of the corresponding order status enum class

public  enum OrderStatusEnum { 

    CREATE_EVENT ( 1, "Create Order" ), 
    FORMAL_EVENT ( 2, "formal order" ), 
    NEED_PAY ( 3, "to be paid" ), 
    PAY_DONE ( 4, "paid" ), 
    ORDER_FINISHED ( 5, "orders completed " ), 

    ORDER_CANCEL ( . 6," the order has been canceled " ); 

    OrderStatusEnum ( int Status, String desc) {
         the this .status = Status;
         the this .desc = desc; 
    } 

    public  int Status; 

    public String desc; 
}

 

Enum class need to be ready status information.

First with a diagram to describe the entire working mechanism:

 

Then the part of the core code needed: a management order status transfer station manager class, a set of classes for operator order twisted state, performing a logic operation subsequent processor type After a twisted state set order.

The class manager required current corresponding to the incoming order status, this result should be obtained in order to perform operations on the status line (corresponding to rely opertor class), then performs a series of operations required for the business logic (written in the corresponding class processor). The advantage is that the transfer order status and the corresponding business processes decoupling . And will no longer have a bunch of complicated operations if ... else. Whenever the need for new operational flow order status, you can write to the corresponding set of operator and processor components to complete, and the separation of the existing services is high.

Examples Next, the code stickers

 
  
/ ** 
 * Order Status Circulation Manager - the core components of the state machine 
 * @author the Java fresh platform for electronic business 
 * 
 * * /
@Component
public class OrderStateManager {

    Map<Integer, AbstractOrderOperator> orderOperatorMaps = new HashMap<Integer, AbstractOrderOperator>();

    Map<Integer, AbstractOrderProcessor> orderProcessorMaps = new HashMap<Integer, AbstractOrderProcessor>();

    public OrderStateManager() { }

    /**
     * 状态流转方法
     * @param orderId 订单id
     * @param event 流转的订单操作事件
     * @param status 当前订单状态
     * @return 扭转后的订单状态
     */
    public int handleEvent(final String orderId, OrderStatusEnum event, final int status) {
        if (this.isFinalStatus(status)) {
            throw new IllegalArgumentException("handle event can't process final state order.");
        }
        // 获取对应处理器,根据入参状态和时间获取订单流转的结果状态
        AbstractOrderOperator abstractOrderOperator = this.getStateOperator(event);
        int resState = abstractOrderOperator.handleEvent(status, event);
        // 得到结果状态,在对应的processor中处理订单数据及其相关信息
        AbstractOrderProcessor orderProcessor = this.getOrderProcessor(event);
        if (!orderProcessor.process(orderId, resState)) {
            throw new IllegalStateException(String.format("订单状态流转失败,订单id:%s", orderId));
        }
        return resState;
    }

    /**
     * 根据入参状态枚举实例获取对应的状态处理器
     * @param event event
     * @return
     */
    private AbstractOrderOperator getStateOperator(OrderStatusEnum event) {
        AbstractOrderOperator operator = null;
        for (Map.Entry<Integer, AbstractOrderOperator> entry: orderOperatorMaps.entrySet()) {
            if (event.status == entry.getKey()) {
                operator = entry.getValue();
            }
        }
        if (null == operator) {
            throw new IllegalArgumentException(String.format("can't find proper operator. The parameter state :%s", event.toString()));
        }
        return operator;
    }

    /**
     * 根据入参状态枚举实例获取对应的状态后处理器
     * @param event event
     * @return
     */
    private AbstractOrderProcessor getOrderProcessor(OrderStatusEnum event) {
        AbstractOrderProcessor processor = null;
        for (Map.Entry<Integer, AbstractOrderProcessor> entry : orderProcessorMaps.entrySet()) {
            if (event.status == entry.getKey()) {
                processor = entry.getValue();
            }
        }
        if (null == processor) {
            throw new IllegalArgumentException(String.format("can't find proper processor. The parameter state :%s", event.toString()));
        }
        return processor;
    }

    /**
     * 判断是不是已完成订单
     * @param status 订单状态码
     * @return
     */
    private boolean isFinalStatus(int status) {
        return OrderStatusEnum.ORDER_FINISHED.status == status;
    }

}

 

核心的代码就是类中的 handleEvent 方法。

对应的获取到的组件处理类示例:

/**
 * @author Java生鲜电商平台-订单模块状态机架构设计
 **/
@Data
public abstract class AbstractOrderOperator {

    int status;

    public abstract int handleEvent(int orderStatus, OrderStatusEnum orderStatusEnum);
}
===================================
/**
 * 创建订单操作状态流转
 * Java生鲜电商平台-订单模块状态机架构设计
 **/
@Component
@OrderOperator
public class CreateOrderOperator extends AbstractOrderOperator {

    public CreateOrderOperator() {
        super.setStatus(1);
    }

    @Override
    public int handleEvent(int orderStatus, OrderStatusEnum orderStatusEnum) {
        if (orderStatus != OrderStatusEnum.CREATE_EVENT.status && orderStatus != OrderStatusEnum.ORDER_CANCEL.status) {
            throw new IllegalArgumentException(String.format("create operation can't handle the status: %s", orderStatus));
        }
        System.out.println("进入创建订单状态扭转处理器...");
        switch (orderStatusEnum) {
            case CREATE_EVENT:
                return OrderStatusEnum.FORMAL_EVENT.status;
            case ORDER_CANCEL:
                return OrderStatusEnum.ORDER_CANCEL.status;
            default:
                return getStatus();
        }
    }
}

 

后处理器

/**
 * 订单处理器
 **/
@Data
public abstract class AbstractOrderProcessor {

    int status;

    public abstract boolean process(String orderId, Object... params);
}
@Component @OrderProcessor public class CreateOrderProcessor extends AbstractOrderProcessor{ public CreateOrderProcessor() { super.setStatus(1); } @Override public boolean process(String orderId, Object... params) { // TODO 创建/取消订单对应的数据库修改,mq发送等操作,可以在此处process方法中完成 System.out.println("进入创建订单后处理器..."); return true; } }

 

这些组件类都是依赖于spring的组件扫描注入。如果要定制化地处理自己的组件类。可以用一些其他的技巧来处理。比如此处使用到了自定义注解,通过自定义注解+自定义状态机初始化类来完成对应组件类的筛选与初始化。将这个初始化类加载完毕,状态机就可以正常使用了。

/**
 * 状态机前置激活类,在spring中扫描配置此类 <br/>
 * 使用自定义注解标记对应的状态处理器和后置处理器并在初始化操作中完成对应处理器的初始化。
 **/
@Component
public class Initialization implements BeanPostProcessor {

    @Resource
    OrderStateManager manager;

    @Nullable
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (bean instanceof AbstractOrderOperator && bean.getClass().isAnnotationPresent(OrderOperator.class) ) {
            AbstractOrderOperator orderState = (AbstractOrderOperator) bean;
            manager.orderOperatorMaps.put(orderState.getStatus(), orderState);
        }
        if (bean instanceof AbstractOrderProcessor && bean.getClass().isAnnotationPresent(OrderProcessor.class) ) {
            AbstractOrderProcessor orderProcessor = (AbstractOrderProcessor) bean;
            manager.orderProcessorMaps.put(orderProcessor.getStatus(), orderProcessor);
        }
        return bean;
    }
}

这里有一个问题就是在正式开发环境中,依赖于项目的spring环境,需要在状态机正式运行前将对应的状态扭转组件类(operator和processor)注入到环境中。

 

联系QQ:137071249

QQ群:793305035

Guess you like

Origin www.cnblogs.com/jurendage/p/11818339.html