行为型模式之责任链模式

2020-03-21  本文已影响0人  雪飘千里

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

概念

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

使用场景

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

结构

image.png

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

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

实例

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

/**
 * 优惠券发放单元接口
 */
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;
}

/**
 * 优惠券发放过程单元父类
 */
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;

}
/**
 * 【优惠券发放】参数为空验证
 */
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;
    }
}
/**
 * 优惠券发放任务管理器
 */
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;
                }
            }
        }
    }

}
image.png
    @Autowired
    private CouponGrantProcess couponGrantProcess;


couponGrantProcess.start(param, context);

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

上一篇下一篇

猜你喜欢

热点阅读