带你读《2022技术人的百宝黑皮书》——谈一谈凑单页的那些优雅设计(4)https://developer.aliyun.com/article/1338378?groupCode=taobaotech
各个域需要满足如下条件:
- 支持单个处理和批量处理
- 支持提前阻断
- 支持前置判断是否需要处理
处理类类图如下
【ChainBaseHandler】:核心处理类
【CartHandler】:加购域处理类
【ItemSupplementHandler】:商品域处理类
【RankingHandler】:榜单域处理类
【RequestHanlder】:参数域处理类
我们首先来看核心处理层
public class ChainBaseHandler<T extends Context> { 2 /** * 任务执行 * @param context */ public void execute(T context) { List<String> executeCommands = Lists.newArrayList(); for (Command<T> c : commands) { try { // 前置校验 if (!c.check(context)) { continue; } // 执行 boolean isContinue = timeConsuming(() -> execute(context, c), c, executeCommands); if (!isContinue) { break; } } catch (Throwable e) { // 打印异常信息 GatherContext.debug("exception", c.getClass().getSimpleName()); GatherContext.error(c.getClass().getSimpleName() + " catch exception", e); } } // 打印个命令任务耗时 GatherContext.debug(this.getClass().getSimpleName() + "-execute", executeCommands); ) )
中间的timeConsuming方法用来计算耗时,耗时需要前后包裹执行方法
private boolean timeConsuming(Supplier<Boolean> supplier, Command<T> c, List<String> execute- Commands) { long startTime = System.currentTimeMillis(); boolean isContinue = supplier.get(); long endTime = System.currentTimeMillis(); long timeConsuming = endTime - startTime; executeCommands.add(c.getClass().getSimpleName() + ":" + timeConsuming); return isContinue; }
具体执行如下:
/** * 执行每个命令 * @return 是否继续执行4 */ private <D extends ContextData> boolean execute(Context context, Command<T> c) { if (context instanceof MuchContext) { return execute((MuchContext<D>) context, c); 8 } if (context instanceof OneContext) { return execute((OneContext<D>) context, c); 11 } return true; ) /** * 单数据执行 * @return 是否继续执行 */ private <D extends ContextData> boolean execute(OneContext<D> oneContext, Command<T> c) { if (Objects.isNull(oneContext.getData())) { return false; } if (c instanceof CommonCommand) { return ((CommonCommand<OneContext<D>>) c).execute(oneContext); } return true; } /** * 批量数据执行 * @return 是否继续执行 */ private <D extends ContextData> boolean execute(MuchContext<D> muchContext, Command<T> c) { if (CollectionUtils.isEmpty(muchContext.getData())) { return false; } if (c instanceof SingleCommand) { muchContext.getData().forEach(data -> ((SingleCommand<MuchContext<D>, D>) c).execute (data, muchContext)); return true; } if (c instanceof CommonCommand) { return ((CommonCommand<MuchContext<D>>) c).execute(muchContext); } return true;
带你读《2022技术人的百宝黑皮书》——谈一谈凑单页的那些优雅设计(6)https://developer.aliyun.com/article/1338376?groupCode=taobaotech