美文网首页
行为型模式之责任链模式

行为型模式之责任链模式

作者: 雪飘千里 | 来源:发表于2020-03-21 14:51 被阅读0次

    行为型模式:类和对象如何交互,划分责任和算法,即对象之间通信。

    概念

    所谓责任链,多个对象组成一条链,每个对象有其不同的处理逻辑,将一个请求从链的的首端发出,沿着链的路径依次传递给链上的每个对象,直到有对象处理这个请求为止。

    使用场景

    1. 多个对象可以处理同一个请求,但具体由哪个对象处理则在运行时动态决定。
    2. 在请求处理者不明确的情况下向对个对象中的一个提交一个请求。
    3. 需要动态处理一组对象处理请求。

    结构

    image.png

    角色介绍
    Handler:抽象处理者角色,声明一个请求处理的方法,并在其中保持一个对下一个处理节点Handler对象的引用。

    ConcreteHandler:具体处理者角色,对请求进行处理,如果不能处理则将该请求转发给下一个节点上的处理对象。

    实例

    简单是实现,这里就不介绍了,网上资源一大把,但是工作中实际很少这样使用,因为很不方便,下面介绍中工作中改造过的责任链模式

      1. 首先创建一个接口,抽象出链上对象要处理的方法run和直接方法前的资格判断can,如下
    /**
     * 优惠券发放单元接口
     */
    public interface ICouponGrantProcessCell {
        /**
         * 任务单元名称.
         * @return Sting
         * 
         */
        String getName();
        
        /**
         * 是否可以运行本任务单元.
         * @param param
         * @param context
         * @return
         */
        boolean can(CouponGrantParam param, CouponGrantProcessContext context);
    
        /**
         * 执行本任务单元.
         * @param param
         * @param context
         * @return
         * @throws Exception
         */
        boolean run(CouponGrantParam param, CouponGrantProcessContext context) throws Exception;
    }
    
    
      1. 然后新建一个抽象基础类,用来抽象具体处理业务的handler
    /**
     * 优惠券发放过程单元父类
     */
    public abstract class BaseCouponGrantProcessCell implements ICouponGrantProcessCell {
        protected Logger logger = LoggerFactory.getLogger(getClass());
    
        @Override
        public String getName() {
            return getClass().getName();
        }
    
        @Override
        public boolean can(CouponGrantParam param, CouponGrantProcessContext context) {
            return true;
        }
    
        @Override
        public boolean run(CouponGrantParam param, CouponGrantProcessContext context) throws Exception {
            boolean resultFlag = true;
            try {
                logger.info("\n----开始执行:" + getName());
                // 1:子类执行下单过程单元
                resultFlag = runing(param, context);
                // 2:下面保存日志
                ////////////////////////
            } catch (Exception e) {
                logger.error("下单过程执行到" + getName() + "出错", e);
                throw new Exception(e);
            }
            return resultFlag;
        }
    
        public abstract boolean runing(CouponGrantParam param, CouponGrantProcessContext context) throws Exception;
    
    }
    
      1. 具体业务处理子类1,这里的具体业务不用关心
    /**
     * 【优惠券发放】参数为空验证
     */
    public class ParamEmptyValidateCell extends BaseCouponGrantProcessCell {
        
        @Autowired
        private IConsumerService consumerService;
        
        @Autowired
        private MarketingActivityService marketingActivityService;
    
        @Autowired
        private IStoreService storeService;
    
        @Override
        public boolean runing(CouponGrantParam param, CouponGrantProcessContext context) throws Exception {
            if (param == null)
                throw new BusinessException("【优惠券发放】参数CouponGrantParam不能为空");
            if (param.getConsumerId() == null)
                throw new BusinessException("【优惠券发放】消费者ID不能为空");
            if (param.getActivityId() == null)
                throw new BusinessException("【优惠券发放】活动ID不能为空");
            if (param.getShopId() == null)
                throw new BusinessException("【优惠券发放】ShopId不能为空");
            
            Consumer consumer = consumerService.getConsumerById(param.getConsumerId());
            if (null == consumer) {
                throw new BusinessException("【优惠券发放】消费者信息不存在");
            }
            context.setConsumer(consumer);
            
            MarketingActivity marketingActivity = marketingActivityService.getMarketingActivity(param.getActivityId());
            if (null == marketingActivity) {
                throw new BusinessException("【优惠券发放】营销活动信息不存在");
            }
            context.setMarketingActivity(marketingActivity);
            
            PointPlace pointPlace = storeService.getStoreByPointId(param.getShopId());
            if (null == pointPlace) {
                throw new BusinessException("【优惠券发放】店铺信息不存在");
            }
            context.setPointPlace(pointPlace);
            
            return true;
        }
    
    }
    

    具体业务处理子类2

    /**
     * 【优惠券发放】优惠券发放过程处理
     */
    public class CouponGrantCell extends BaseCouponGrantProcessCell {
        
        @Autowired MCouponConsumerService mCouponConsumerService;
        
        @Override
        public boolean can(CouponGrantParam param, CouponGrantProcessContext context) {
            return param.getWhetherGrant();
        }
        
        @Override
        public boolean runing(CouponGrantParam param, CouponGrantProcessContext context) throws Exception {
            // 最终领取的优惠券信息
            List<MCouponConsumer> couponConsumers = new ArrayList<MCouponConsumer>();
            
            PointPlace pointPlace = context.getPointPlace();
            
            // 发放优惠券
            List<MarketingActivityCoupon> gettableCoupons = context.getGettableCoupons();
            // 生成领取批次,用户单次领取的批次号一致
            String getBatch = RandomUtil.getCharAndNumr(16);
            gettableCoupons.parallelStream().forEachOrdered(activityCoupon -> {
                // 取得此份权益发放张数(打包发放数量)
                int packageQty = activityCoupon.getPackageQty();
                for (int i = 0; i < packageQty; i++) {
                    
                    MCouponConsumer mCouponConsumer=mCouponConsumerService.getCouponConsumer(activityCoupon,System.currentTimeMillis());
                    mCouponConsumer.setConsumerId(param.getConsumerId());
                    mCouponConsumer.setMarketingActivityId(param.getActivityId());
                    mCouponConsumer.setMarketingType(1);
                    mCouponConsumer.setGetBatch(getBatch);
                    mCouponConsumer.setShopId(pointPlace.getId());
                    mCouponConsumer.setShopName(pointPlace.getPointName());
                    mCouponConsumerService.saveMCouponConsumer(mCouponConsumer);
                    
                    couponConsumers.add(mCouponConsumer);
                }
                
            });
            context.setCouponConsumers(couponConsumers);
                                
            return true;
        }
    }
    
      1. 新建责任链执行过程管理器
    /**
     * 优惠券发放任务管理器
     */
    public class CouponGrantProcess {
        private Logger logger = LoggerFactory.getLogger(getClass());
        /**
         * 
         */
        private List<ICouponGrantProcessCell> tasks = null;
    
        public void setTasks(List<ICouponGrantProcessCell> tasks) {
            Assert.notNull(tasks);
            Assert.notEmpty(tasks);
            this.tasks = tasks;
            logger.info("初始化couponGrantProcess Tasks成功");
        }
    
        public void start(CouponGrantParam param, CouponGrantProcessContext context) throws Exception {
            for (int index = 0; index < this.tasks.size(); index++) {
                ICouponGrantProcessCell task = this.tasks.get(index);
                boolean flag = task.can(param, context);
                if (flag) {
                    try {
                        boolean isNext = task.run(param, context);
                        if (!isNext) {
                            break;
                        }
                    } catch (Exception e) {
                        logger.error("终止处理该couponGrantProcess", e);
                        throw e;
                    }
                }
            }
        }
    
    }
    
      1. xml文件中配置业务类和管理类
    image.png
      1. 调用责任链
        @Autowired
        private CouponGrantProcess couponGrantProcess;
    
    
    couponGrantProcess.start(param, context);
    

    从改造后的责任链中,可以很明显的看出,链上新添加处理类的话,特别方便,同时,管理起来也很方便。

    相关文章

      网友评论

          本文标题:行为型模式之责任链模式

          本文链接:https://www.haomeiwen.com/subject/vuldyhtx.html