设计模式之状态模式

状态模式(State Pattern):类的行为是基于它的状态改变的。这种类型的设计模式属于行为型模式。

在状态模式中,我们创建表示各种状态的对象和一个行为随着状态对象改变而改变的 context 对象。

案例示例

最常见地就是订单状态变更;将对应状态变更需要执行的业务逻辑封装到单独的类中,便于代码的维护

代码示例

下面以商城订单状态变更案例来举例。

定义状态操作接口

public interface MallOrderState {

    /**
     * 订单状态业务操作
     * @param orderNo 订单号
     * @return  返回操作结果
     */
    String changeState(String orderNo);

    // TODO 这里还可以定义更多的方法
}

状态操作接口抽象类

之所以增加这么一个中间的抽象类,是为了实现接口一些默认的实现,避免后面增加新的方法时,每个状态操作类都需要去实现。

public abstract class AbstractMallOrderState implements MallOrderState {

    public final MallOrderDao mallOrderDao;

    public AbstractMallOrderState(MallOrderDao mallOrderDao) {
        this.mallOrderDao = mallOrderDao;
    }

    /**
     * 订单状态业务操作
     * @param orderNo 订单号
     * @return  返回操作结果
     */
    @Override
    public String changeState(String orderNo) { 
        // 这里还可以做些公共的操作
        MallOrder mallOrder = mallOrderDao.findByOrderNo(orderNo);
        return exec(mallOrder);
    }

    /**
     * 进行实际的操作
     * @param mallOrder 订单信息
     * @return  返回操作结果
     */
    public abstract String exec(MallOrder mallOrder);

}

对应订单状态的实际业务操作类

取消订单操作

@Component
public class CancelMallOrderState extends AbstractMallOrderState {

    public CancelMallOrderState(MallOrderDao mallOrderDao) {
        super(mallOrderDao);
    }

    /**
     * 取消操作
     */
    @Override
    public String exec(MallOrder mallOrder)  {
        OrderStatus status = mallOrder.getStatus();

        if(status==OrderStatus.CANCEL){
            return "订单已取消";
        }
        if(status!=OrderStatus.WAIT_PAY){
            return "订单状态已变更,不允许此操作";
        }
        boolean updateOk = this.mallOrderDao.updateStatus(mallOrder.getOrderNo(), OrderStatus.CANCEL);
        if(updateOk){
            return "取消成功";
        }
       return "服务繁忙,请稍后再试";
    }
}

发货操作

@Component
public class ShipMallOrderState extends AbstractMallOrderState {

    public ShippMallOrderState(MallOrderDao mallOrderDao) {
        super(mallOrderDao);
    }

    /**
     * 发货操作
     */
    @Override
    public String exec(MallOrder mallOrder)  {
        OrderStatus status = mallOrder.getStatus();

        if(status!=OrderStatus.WAIT_SHIPPED){
            return "订单状态已变更,不允许此操作";
        }
        boolean updateOk = this.mallOrderDao.updateStatus(mallOrder.getOrderNo(), OrderStatus.SHIPPED);
        if(updateOk){
            return "发货成功";
        }
       return "服务繁忙,请稍后再试";
    }
}

定义状态操作类的工厂方法

@Component
public class MallOrderStateFactory {

    @Autowired
    private CancelMallOrderState cancelMallOrderState;

    @Autowired
    private ShipMallOrderState shipMallOrderState;

    public MallOrderState getOrderState(MallOrderOpera orderOpera){
        switch (orderOpera){
            case SHIPPED:
                return shipMallOrderState;
            case CANCEL:
                return cancelMallOrderState;
            default:
                return null;
        }
    }
}

实际业务中调用

@Service
public class MallOrderServiceImpl implements MallOrderService {

    @Autowired
    private MallOrderStateFactory mallOrderStateFactory;

    /**
     * 取消订单
     * @param orderNo 订单号
     * @return 返回结果
     */
    @Override
    public String cancel(String orderNo) {
        return mallOrderStateFactory.getOrderState(MallOrderOpera.CANCEL).changeState(orderNo);
    }

    /**
     * 发货
     * @param orderNo 订单号
     * @return 返回结果
     */
    @Override
    public String ship(String orderNo) {
        return mallOrderStateFactory.getOrderState(MallOrderOpera.SHIPPED).changeState(orderNo);
    }

}

这样进行拆分后会让代码更加的简洁,每次去维护时目的会更明确;如果写在一起的话,在进行维护的时候就会是一大坨的代码,如果逻辑复杂的话看起来会很恼火。

关注微信订阅号‘起岸星辰’获取最新资讯

原文地址:https://www.cnblogs.com/vchar/p/14347152.html