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