责任链模式在工作中应用

需求:

判断配件是否需要抽检,现在系统有三种抽检规则:商品规则,组织规则,其它规则,配件满足任一规则即需要抽检
因为配件要依次经过三种规则,所以考虑使用责任链模式:让配件依次匹配商品规则,组织规则,其它规则,满足任一规则即返回,不满足继续用下一规则判断。

代码:

代码结构:
在这里插入图片描述
1.策略模版,创建一个抽象类:CommonInspectionHandler

/**
 * 抽检规则处理器
 */
@Slf4j
public abstract class CommonInspectionHandler {

    /**
     * 获取操作标识(一定要有,区分不同的处理人)
     */
    abstract InspectionRuleOperationBizTypeEnum getHandlerBizType();

    /**
     * 下一个处理人(一定要有)
     */
    public CommonInspectionHandler nextCommonInspectionHandler ;

    /**
     * 取值方法
     */
    public CommonInspectionHandler getNextCommonInspectionHandler() {
        return nextCommonInspectionHandler;
    }

    /**
     * 给当前对象指定下一处理人,并返回【下一处理人】
     */
    public CommonInspectionHandler setNextCommonInspectionHandler(CommonInspectionHandler next) {
        this.nextCommonInspectionHandler = next;
        log.info("当前处理人:"+this.getHandlerBizType().getDesc()+",的下一处理人:"+next.getHandlerBizType().getDesc());
        return next;
    }

    /**
     * 明细判断是否需抽检:核心方法doChain:如果当前TranslineQueryHandler可以解决,就解决,如果不行,就调此方法交给next去解决
     * @param inspectionOrderDetailDTOS 抽检明细
     */
    public final void doChain(List<InspectionOrderDetailDTO> inspectionOrderDetailDTOS) {
        List<InspectionOrderDetailDTO> needSimpleOrderDetailDTOs = deal(inspectionOrderDetailDTOS);
        //如果配件都需要抽检,直接返回(退出责任链),不需要再走规则判断配件是否需要抽检
        List<InspectionOrderDetailDTO> handleOrderDetails = needSimpleOrderDetailDTOs.stream()
                .filter(e -> !e.isNeedInspection())
                .collect(toList());
        if (CollectionUtils.isEmpty(handleOrderDetails)) {
            return;
        }
        //如果还有配件不需要抽检&&还有抽检规则未匹配,匹配下一抽检规则(继续责任链)
        if (getNextCommonInspectionHandler() != null) {
            getNextCommonInspectionHandler().doChain(inspectionOrderDetailDTOS);
        }
    }

    /**
     * 判断配件是否需要抽检:抽象方法deal:用于处理请求,所有处理人都要根据自身条件重写此方法
     * @param inspectionOrderDetailDTOS 抽检明细
     * @return 需要抽检的orderDetailIds
     */
    public abstract List<InspectionOrderDetailDTO> deal(List<InspectionOrderDetailDTO> inspectionOrderDetailDTOS);


}

重点关注下列方法:
方法1:getHandlerBizType(),区分处理对象
方法2:setNextCommonInspectionHandler(),设置当前处理对象的下一处理对象
方法3:deal(),抽象方法,处理请求
方法4:doChain(),用于将参数传递给下一个处理对象(根据 需求可定制化,此处判断配件是否需要抽检,如果已满足抽检条件,结束链路返回,如果未满足抽检条件,将数据转交给下一处理对象)。

其中枚举类:InspectionRuleOperationBizTypeEnum:

/**
 * 抽检规则操作记录类型枚举
 */
public enum InspectionRuleOperationBizTypeEnum {

    GOODS(InspectionRuleOperationBizType.GOODS, "商品规则"),
    ORG(InspectionRuleOperationBizType.ORG, "组织规则"),
    OTHER(InspectionRuleOperationBizType.OTHER, "其他规则");

    @Getter
    private Integer type;
    @Getter
    private String desc;

    InspectionRuleOperationBizTypeEnum(Integer type, String desc) {
        this.type = type;
        this.desc = desc;
    }

}

2.责任链上的三个类:
a.商品抽检规则处理器:GoodsRuleHandler


/**
 * 商品抽检规则处理器
 */
@Slf4j
@Component
public class GoodsRuleHandler extends CommonInspectionHandler {

    @Override
    public InspectionRuleOperationBizTypeEnum getHandlerBizType() {
        return InspectionRuleOperationBizTypeEnum.GOODS;
    }

    @Override
    public List<InspectionOrderDetailDTO> deal(List<InspectionOrderDetailDTO> inspectionOrderDetailDTOS) {
        log.info("<1> 开始使用商品规则,判断{}是否需要抽检", inspectionOrderDetailDTOS.stream().map(o->o.getOrderDetailId()).collect(Collectors.toSet()));
        log.info("逻辑代码省略,如果配件符合某商品规则,就给配件打上需要抽检的标签");
        return inspectionOrderDetailDTOS;
    }




};

b.组织抽检规则处理器:OrgRuleHandler

/**
 * 组织抽检规则处理器
 */
@Slf4j
@Component
public class OrgRuleHandler extends CommonInspectionHandler {

    @Override
    public InspectionRuleOperationBizTypeEnum getHandlerBizType() {
        return InspectionRuleOperationBizTypeEnum.ORG;
    }

    @Override
    public List<InspectionOrderDetailDTO> deal(List<InspectionOrderDetailDTO> inspectionOrderDetailDTOS) {
        log.info("<2> 开始使用组织规则,判断{}是否需要抽检", inspectionOrderDetailDTOS.stream().map(o->o.getOrderDetailId()).collect(Collectors.toSet()));
        log.info("逻辑代码省略,如果配件符合组织规则,就给配件打上需要抽检的标签");
        return inspectionOrderDetailDTOS;
    }




}

c.其他抽检规则处理器:OtherRuleHandler

/**
 * 其他抽检规则处理器
 */
@Slf4j
@Component
public class OtherRuleHandler extends CommonInspectionHandler {

    @Override
    public InspectionRuleOperationBizTypeEnum getHandlerBizType() {
        return InspectionRuleOperationBizTypeEnum.OTHER;
    }

    @Override
    public List<InspectionOrderDetailDTO> deal(List<InspectionOrderDetailDTO> inspectionOrderDetailDTOS) {
        log.info("<3> 开始使用其他抽检规则,判断{}是否需要抽检", inspectionOrderDetailDTOS.stream().map(o->o.getOrderDetailId()).collect(Collectors.toSet()));
        log.info("逻辑代码省略,如果配件符合其他规则,就给配件打上需要抽检的标签");
        return inspectionOrderDetailDTOS;
    }




}

3.测试代码:

public class InspectionRuleTest extends BaseTest {
    @Autowired
    private GoodsRuleHandler goodsRuleHandler;
    @Autowired
    private OrgRuleHandler orgRuleHandler;
    @Autowired
    private OtherRuleHandler otherRuleHandler;

    @Test
    public void test1() {
        List<InspectionOrderDetailDTO> inspectionOrderDetailDTOS= Lists.newArrayList();
       
        inspectionOrderDetailDTOS.add(InspectionOrderDetailDTO.builder().orderDetailId(1222).partsName("大灯").needInspection(Boolean.FALSE).build());
        //组装责任链
        goodsRuleHandler.setNextCommonInspectionHandler(orgRuleHandler).setNextCommonInspectionHandler(otherRuleHandler);
        //链头部开始执行
        goodsRuleHandler.doChain(inspectionOrderDetailDTOS);
        for (InspectionOrderDetailDTO i: inspectionOrderDetailDTOS) {
            log.info("配件"+i.getPartsName()+"是否需要抽检:"+i.isNeedInspection());
        }

    }
   }

4.结果:

当前处理人:商品规则,的下一处理人:组织规则
当前处理人:组织规则,的下一处理人:其他规则
<1> 开始使用商品规则,判断[1222]是否需要抽检
逻辑代码省略,如果配件符合某商品规则,就给配件打上需要抽检的标签
<2> 开始使用组织规则,判断[1222]是否需要抽检
逻辑代码省略,如果配件符合组织规则,就给配件打上需要抽检的标签
<3> 开始使用其他抽检规则,判断[1222]是否需要抽检
逻辑代码省略,如果配件符合其他规则,就给配件打上需要抽检的标签
配件大灯是否需要抽检:false

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值