Java设计模式之状态模式


1、解决的问题

订单的状态变化,待支付、待发货、待签收、已取消、已完成,待支付和待发货状态下可以进行支付和取消两个动作。

正常写法:

        String action = "payOrder";
        OrderStateEnum state = OrderStateEnum.WaitPay;

        if (OrderStateEnum.WaitPay.equals(state)) {
            if ("payOrder".equals(action)) {
                System.out.println("支付订单,修改成待发货状态");
                state = OrderStateEnum.WaitDeliver;
            }
            if ("cancel".equals(action)) {
                System.out.println("取消订单,修改成已取消");
                state = OrderStateEnum.Cancel;
            }
        }
        else if(OrderStateEnum.WaitDeliver.equals(state)) {
            if ("deliverOrder".equals(action)) {
                System.out.println("订单发货,修改成待签收状态");
                state = OrderStateEnum.WaitSign;
            }
            if ("cancel".equals(action)) {
                System.out.println("取消订单,修改成已取消");
                state = OrderStateEnum.Cancel;
            }
        }
        //其他判断的省略

        System.out.println("最终的订单状态:" + state.getName());

这种写法如果进行状态的增加,代码会非常复杂,可读性差


2、使用状态模式:

public enum OrderStateEnum {
    /**待支付*/
    WaitPay("待支付"),
    /**待发货*/
    WaitDeliver("待发货"),
    /**待签收*/
    WaitSign("待签收"),
    /**已完成*/
    Finish("已完成"),
    /**已取消*/
    Cancel("已取消");

    private String name;

    OrderStateEnum(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}
public abstract class OrderState {
    private OrderStateContext context;

    public void setContext(OrderStateContext context) {
        this.context = context;
    }

    public OrderStateContext getContext() {
        return context;
    }

    /**
     * 支付订单
     */
    public abstract void payOrder();

    /**
     * 订单发货
     */
    public abstract void deliverOrder();

    /**
     * 用户确认收货
     */
    public abstract void signOrder();

    /**
     * 取消订单
     */
    public abstract void cancelOrder();

    public abstract OrderStateEnum getCurrentState();
}
public class OrderStateContext {

    //定义出所有的订单状态
    public static OrderState waitPayState;
    public static OrderState waitDeliverState;
    public static OrderState waitSignState;
    public static OrderState cancelState;
    public static OrderState finishState;

    public OrderStateContext(String orderId) {
        waitPayState = new WaitPayState(orderId);
        waitDeliverState = new WaitDeliverState(orderId);
        waitSignState = new WaitSignState(orderId);
        cancelState = new CancelState(orderId);
        finishState = new FinishState(orderId);
    }

    /**
     * 当前状态
     */
    private OrderState state;

    public OrderState getState() {
        return state;
    }

    public void setState(OrderState state) {
        this.state = state;
        //把当前的环境通知到各个实现类中
        this.state.setContext(this);
    }

    public void payOrder() {
        this.state.payOrder();
    }

    public void deliverOrder() {
        this.state.deliverOrder();
    }

    public void signOrder() {
        this.state.signOrder();
    }

    public void cancelOrder() {
        this.state.cancelOrder();
    }

}
/**
 * 在订单待发货的状态下能做什么事情
 */
public class WaitDeliverState extends OrderState {

    private String orderId;

    public WaitDeliverState(String orderId) {
        this.orderId = orderId;
    }

    @Override
    public void payOrder() {

    }

    @Override
    public void deliverOrder() {
        System.out.println("订单" + orderId + "发货");
        this.getContext().setState(OrderStateContext.waitSignState);
    }

    @Override
    public void signOrder() {

    }

    @Override
    public void cancelOrder() {
        //状态修改
        this.getContext().setState(OrderStateContext.cancelState);
        //动作委托为cancelState来执行,最终状态
        this.getContext().getState().cancelOrder();
    }

    @Override
    public OrderStateEnum getCurrentState() {
        return OrderStateEnum.WaitDeliver;
    }
}

/**
 * 在订单未支付的状态下能做什么事情
 */
public class WaitPayState extends OrderState {

    private String orderId;

    public WaitPayState(String orderId) {
        this.orderId = orderId;
    }

    @Override
    public void payOrder() {
        //变更状态前,要执行的事件,或者检查条件
        System.out.println("支付" + orderId + "订单");
        //状态修改
        this.getContext().setState(OrderStateContext.waitDeliverState);
    }

    @Override
    public void deliverOrder() {

    }

    @Override
    public void signOrder() {

    }

    @Override
    public void cancelOrder() {
        //状态修改
        this.getContext().setState(OrderStateContext.cancelState);
        //动作委托为cancelState来执行,最终状态
        this.getContext().getState().cancelOrder();
    }

    @Override
    public OrderStateEnum getCurrentState() {
        return OrderStateEnum.WaitPay;
    }
}

public class CancelState extends OrderState {
    private String orderId;

    public CancelState(String orderId) {
        this.orderId = orderId;
    }

    @Override
    public void payOrder() {

    }

    @Override
    public void deliverOrder() {

    }

    @Override
    public void signOrder() {

    }

    @Override
    public void cancelOrder() {
        System.out.println("取消" + orderId + "订单");
    }

    @Override
    public OrderStateEnum getCurrentState() {
        return OrderStateEnum.Cancel;
    }
}


3、运行效果

public static void main(String[] args) {
        OrderStateContext context = new OrderStateContext("11132");
        context.setState(OrderStateContext.waitPayState);//初始状态
        context.payOrder();//订单支付
        System.out.println("订单状态为:" + context.getState().getCurrentState().getName());
        context.deliverOrder();//发货
        System.out.println("订单状态为:" + context.getState().getCurrentState().getName());
        context.cancelOrder();//取消订单
        System.out.println("订单状态为:" + context.getState().getCurrentState().getName());
    }

支付11132订单
订单状态为:待发货
订单11132发货
订单状态为:待签收
取消11132订单
订单状态为:已取消




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值