一个简单的订单状态模式实现

在一般的订单模块中,订单状态是不可或缺的一个因素,订单状态因为业务需要的原因有多种实现,为了避免臃肿和混乱不清的代码结构,我们可以尝试将订单状态的变更抽象出来,单独做变更。

其中设计状态变更的前置代码,亦可在状态模式中处理,(比如订单从未支付到支付,需要去调用第三方支付接口或者其他实现,这个实现就可以在订单状态变更的内部实现。)

创建订单类,作为数据载体:

java 复制代码
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class Order {

    // 状态类
    private OrderState orderState;

    // 订单号
    private String orderNo;

    // 订单状态
    private String status;
}

创建订单状态接口:如果不再细分的话,可以将订单所有涉及状态变更的操作都抽象成方法在这里列出来

java 复制代码
public interface OrderState {

    // 提交订单
    OrderState submit();

    // 支付
    OrderState pay();

    // 取消
    OrderState cancel();

    // 再来一单
    OrderState reBuy();
    
    // 其他订单操作...
}

创建状态接口所有方法的默认处理方式(后面我们具体的订单状态类将继承此抽象类,在这里设置过默认处理后,我们的状态类也不需要实现全部的方法了)

java 复制代码
@Data
@AllArgsConstructor
public abstract class AstractOrderState implements OrderState {

    // 我们要处理的数据
    private Order order;

    /**
    * 根据数据库的状态枚举获取状态类实例
    */
    public static OrderState getOrderStateByState(Order order) {
        switch (order.getStatus()) {
            case "NOSUBMIT":
                return new NotSubmitted(order);
            case "WAITPAY":
                return new WaitPay(order);
            default:
                throw new RuntimeException("状态未知" + order.getStatus());
        }
    }

    @Override
    public OrderState submit() {
        System.out.println("当前状态为:" + this.order.getStatus() + ",不支持提交操作");
        return this;
    }

    @Override
    public OrderState pay() {
        System.out.println("当前状态为:" + this.order.getStatus() + ",不支持付款操作");
        return this;
    }

    @Override
    public OrderState cancel() {
        System.out.println("当前状态为:" + this.order.getStatus() + ",不支持取消操作");
        return this;
    }

    @Override
    public OrderState reBuy() {
        System.out.println("当前状态为:" + this.order.getStatus() + ",不支持再来一单操作");
        return this;
    }
}

创建各个状态的对象,以及编写改对象的代码:

java 复制代码
// 未提交状态
public class NotSubmitted extends AstractOrderState {

    public NotSubmitted(Order order) {
        super(order);
    }
    
    @Override
    public OrderState submit(){
        System.out.println("当前状态:" + this.getOrder().getStatus()+" 已提交");
        // 订单提交代码
        return new Submitted(this.getOrder());
    }

    @Override
    public OrderState cancel(){
        System.out.println("当前状态:" + this.getOrder().getStatus());
        // 订单提交代码
        return new Cancelled(this.getOrder());
    }
}
java 复制代码
// 待支付状态
public class WaitPay extends AstractOrderState {

    public WaitPay(Order order) {
        super(order);
    }
    
    @Override
    public OrderState pay(){
        System.out.println("当前状态:" + this.getOrder().getStatus());
        // 支付代码
        return new Paid(this.getOrder());
    }
    
    @Override
    public OrderState cancel(){
        System.out.println("当前状态:" + this.getOrder().getStatus());
        // 订单提交代码
        return new Cancelled(this.getOrder());
    }
}
java 复制代码
// 订单已完成状态
public class Done extends AstractOrderState {
    
    public Done(Order order) {
        super(order);
    }
    
    @Override
    public OrderState reBuy(){
        System.out.println("当前状态:" + this.getOrder().getStatus());
        // 再次购买代码
        return new NotSubmitted(this.getOrder());
    }
    
    @Override
    public OrderState cancel(){
        System.out.println("当前状态:" + this.getOrder().getStatus());
        // 订单提交代码
        return new Cancelled(this.getOrder());
    }
}

从代码中我们可以看出,不同的状态类只需要实现自己所能处理的方法即可,这样我们就将不同状态的职责划分给不同状态类了,这可以帮助我们更好的处理订单状态变更,当然这只是一个demo,想要使用订单状态模式去处理自己的需求还需要大家根据自己的工作需求去写不同的实现。归根到底这种设计模式只是将看似有共同点的不同处理划分成一类,然后再在此类中细分,如果我们有其他的类似需求也是可以用到上述设计模式的。

测试:

java 复制代码
public class OrderController {
    public static void main(String[] args) {
        Order order = Order.builder()
                .status("NOSUBMIT")
                .build();
        order.setOrderState(AstractOrderState.getOrderStateByState(order));
        order.getOrderState().reBuy();
    }
}

这里我们创建一个未提交状态的订单,并且让他调用reBuy()方法,发现此状态没有实现reBuy()方法,代码就会走到我们的默认方法中,然后报错:

java 复制代码
public class OrderController {
    public static void main(String[] args) {
        Order order = Order.builder()
                .status("NOSUBMIT")
                .build();
        order.setOrderState(AstractOrderState.getOrderStateByState(order));
        order.getOrderState().submit();
    }
}

当我们使用未提交状态去调用提交方法时,因为未提交状态类实现了此方法,就会走该实现,正常打印结果。

相关推荐
魔道不误砍柴功33 分钟前
使用 Function 来编写策略模式:优雅而高效的设计模式实践
设计模式·策略模式
-权子-2 小时前
设计模式 - 策略模式Strategy
设计模式·策略模式
Niuguangshuo2 小时前
Python设计模式:策略模式
python·设计模式·策略模式
搞不懂语言的程序员6 小时前
中介者模式详解及真实场景解决方案
设计模式·中介者模式
Koma-forever20 小时前
java设计模式-单例模式
java·单例模式·设计模式
Koma-forever20 小时前
java设计模式-建造者模式
java·设计模式·建造者模式
magic 2451 天前
Java中23种设计模式之代理模式
设计模式·代理模式
浅陌sss1 天前
设计模式 --- 状态模式
设计模式
叶甯1 天前
【设计模式】单例模式
设计模式
诺亚凹凸曼1 天前
23种设计模式-行为型模式-模板方法
设计模式