最近在工作中,涉及到元数据的特殊处理,由于系统需要兼容多级经销商和多组织模式;对于不同的租户类型、不同的业务控制方式、不同的登录用户,同一模块的元数据存在差异。
注:此处的【元数据】用于构建前端界面的基本元素,前端调用服务获取元数据后构建界面
在原有的逻辑中,代码堆砌在一个叫做handPartCorpBillItems的方法中,通过一系列的if---elseif进行处理。如下所示,由于业务比较多,实际的代码行数很长,不便于维护。
private List<CorpBillItem> handPartCorpBillItems(Long billId,List<CorpBillItem> corpBillItems){
MetaHandlerChain.executeHandlerChain(billId, MetaType.BILL_ITEM, corpBillItems);
CoreContext context = AppContext.getBizContext();
BizMode bizMode = context.getTokenDetail().getBizMode();
boolean isMultiBizs = BizMode.SINGLEBIZS.equals(bizMode) || BizMode.MULTIBIZS.equals(bizMode);
boolean isMultiOrgs = BizMode.MULTI.equals(bizMode) || BizMode.MULTIBIZS.equals(bizMode);
if(CUSTOMERGROUP.equals(billId)) {
if(context.getTokenDetail().getUserType().isTenantType() && isMultiBizs) {
corpBillItems.parallelStream().filter(item -> null != item && APPLICATIONSCOPE.equals(item.getFieldName()))
.forEach(item -> item.setIsHidden(false));
}else {
corpBillItems.parallelStream().filter(item -> null != item && APPLICATIONSCOPE.equals(item.getFieldName()))
.forEach(item -> item.setIsHidden(true));
}
}
if (CHANNELAGENTDETAIL.equals(billId) && BizMode.SINGLEBIZS.equals(bizMode)){
corpBillItems.parallelStream().filter(item -> null != item && DEPARTMENTID.equals(item.getFieldName()))
.forEach(item -> item.setIsShowIt(false));
}
}
在改造中,使用责任链模式,将对元数据的处理进行抽象,并进行封装。设计结构如下:
抽象类AbstractHandler<T>定义和封装了责任链的相关逻辑。具体代码如下:
public abstract class AbstractHandler<T> {
private final Logger logger = LoggerFactory.getLogger(AbstractHandler.class);
/**
* 需要处理的metaId
*/
protected Long metaId;
/**
* 元数据类型
*/
protected MetaType metaType;
/**
* 责任链中的下一个处理类
*/
protected AbstractHandler<T> nextHandler;
protected FunctionOptionService functionOptionService;
/**
* 无参构造
*/
public AbstractHandler() {
}
/**
* 有参构造
* @param metaId 元数据id
* @param metaType 元数据类型
* @param functionOptionService 服务
*/
public AbstractHandler(Long metaId, MetaType metaType, FunctionOptionService functionOptionService) {
this.metaId = metaId;
this.metaType = metaType;
this.functionOptionService = functionOptionService;
}
/**
* 设置下一个处理器
* @param nextHandler 下一个处理器
*/
public void setNextHandler(AbstractHandler<T> nextHandler) {
this.nextHandler = nextHandler;
}
/**
* 外部调用处理类
* @param metaId 元数据id
* @param metaType 元数据类型
* @param metaList 需要处理的数据
*/
public void handler(Long metaId, MetaType metaType, List<T> metaList){
logger.info("元数据处理开始---元数据id:{},元数据处理类型:{},入参:{}", metaId, metaType, AppContext.toJson((Serializable)metaList));
handler(metaType, metaList);
if(nextHandler !=null){
nextHandler.handler(metaId, metaType, metaList);
}
logger.info("元数据处理结束---出参:{}", AppContext.toJson((Serializable)metaList));
}
/**
* 根据metaId具体的处理逻辑
* @param metaType 元数据类型
* @param metaList 元数据处理
*/
abstract protected void handler(MetaType metaType, List<T> metaList);
}
责任链处理模式中,处理类在一个链式结构中,按顺序对数据进行处理。
责任链构建及执行类方代码如下:
public class MetaHandlerChain{
public static Long ENTERPRISE_ORDER_LIST = 3L;
public static Long AGENT_ORDER_DETAIL = 198L;
private static final Long[] PRICE_CENTER = new Long[]{50L,68L,69L,87L,89L,90L,95L,97L,100L,112L,141L,143L,145L,230L};
/**
* 构建元数据处理链
*@param metaId 元数据id
* @param metaType 元数据类型
* @param metaList 代处理数据
* @param <T> class
* @return AbstractHandler
*/
private static FunctionOptionService functionOptionService;
@Autowired
public void setUserRepository(FunctionOptionService functionOptionService){
MetaHandlerChain.functionOptionService=functionOptionService;
}
private static <T> AbstractHandler<T> getMetaHandlerChain(Long metaId, MetaType metaType, List<T> metaList){
AbstractHandler<T> handler = new CommonHandler<>(metaId, metaType, functionOptionService);
if(metaId.equals(ENTERPRISE_ORDER_LIST)) {
handler.setNextHandler(new OrderMetaHandler<>(metaId, metaType, functionOptionService));
}else if(Arrays.binarySearch(PRICE_CENTER,metaId) >= 0) {
handler.setNextHandler(new PriceCenterMetaHandler<T>(metaId, metaType, functionOptionService));
}
return handler;
}
/**
* 处理链执行
* @param metaId 元数据id
* @param metaType 元数据类型
* @param metaList 代处理数据列表
* @param <T> class
*/
public static <T>void executeHandlerChain(Long metaId, MetaType metaType, List<T> metaList) {
getMetaHandlerChain(metaId, metaType, metaList).handler(metaId, metaType, metaList);
}
}