zoukankan      html  css  js  c++  java
  • 设计模式之状态模式

    状态模式(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);
        }
    
    }
    

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

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

  • 相关阅读:
    多个类定义attr属性重复的问题:Attribute "xxx" has already been defined
    好用的批量改名工具——文件批量改名工具V2.0 绿色版
    得到ImageView中drawable显示的区域的计算方法
    得到view坐标的各种方法
    实现类似于QQ空间相册的点击图片放大,再点后缩小回原来位置
    Material Designer的低版本兼容实现(五)—— ActivityOptionsCompat
    Android 自带图标库 android.R.drawable
    解决 Attempting to destroy the window while drawing!
    解决Using 1.7 requires compiling with Android 4.4 (KitKat); currently using API 4
    Material Designer的低版本兼容实现(四)—— ToolBar
  • 原文地址:https://www.cnblogs.com/vchar/p/14347152.html
Copyright © 2011-2022 走看看