前言
1、什么是管道模式
管道模式不属于我们常说的23种设计模式中的一种,它可以看成是责任链模式的一种变体。所谓的管道模式用技术话来说,就是把数据传递给一个任务队列,由任务队列按次序依次对数据进行加工处理。
2、什么样的场景适合用管道模式
当业务流程比较复杂时,需要拆分成多个子步骤,且每个子步骤可以自由组合,替换,新增,删除的场景
实现管道的一般套路
1、封装管道数据透传上下文
public class ChannelHandlerContext extends ConcurrentHashMap<String,Object> { protected static Class<? extends ChannelHandlerContext> contextClass = ChannelHandlerContext.class; protected static final TransmittableThreadLocal<? extends ChannelHandlerContext> CHAIN_CONTEXT = new TransmittableThreadLocal<ChannelHandlerContext>() { @Override protected ChannelHandlerContext initialValue() { try { return contextClass.getDeclaredConstructor().newInstance(); } catch (Throwable e) { throw new RuntimeException(e); } } }; /** * 覆盖默认的管道上下文 * * @param clazz */ public static void setContextClass(Class<? extends ChannelHandlerContext> clazz) { contextClass = clazz; } /** * 获取当前管道上下文 * * */ public static final ChannelHandlerContext getCurrentContext() { return CHAIN_CONTEXT.get(); } /** * 释放上下文资源 * * @return */ public void release() { this.clear(); CHAIN_CONTEXT.remove(); } /** * * 获取上下文默认值 * @param key * @param defaultValue * @return */ public Object getDefault(String key, Object defaultValue) { return Optional.ofNullable(get(key)).orElse(defaultValue); } public static final String CHANNEL_HANDLER_REQUEST_KEY = "channelHandlerRequest"; public ChannelHandlerRequest getChannelHandlerRequest() { return (ChannelHandlerRequest) this.getDefault(CHANNEL_HANDLER_REQUEST_KEY,ChannelHandlerRequest.builder().build()); } }
2、定义管道抽象执行器
public abstract class AbstactChannelHandler { private String channelHandlerName; public String getChannelHandlerName() { return channelHandlerName; } public void setChannelHandlerName(String channelHandlerName) { this.channelHandlerName = channelHandlerName; } public abstract boolean handler(ChannelHandlerContext chx); }
3、定义管道
@Slf4j public class ChannelPipeline { private LinkedBlockingDeque<AbstactChannelHandler> channelHandlers = new LinkedBlockingDeque(); private ChannelHandlerContext handlerContext; public ChannelPipeline addFirst(AbstactChannelHandler channelHandler){ return addFirst(null,channelHandler); } public ChannelPipeline addLast(AbstactChannelHandler channelHandler){ return addLast(null,channelHandler); } public ChannelPipeline addFirst(String channelHandlerName,AbstactChannelHandler channelHandler){ if(StringUtils.isNotBlank(channelHandlerName)){ channelHandler.setChannelHandlerName(channelHandlerName); } channelHandlers.addFirst(channelHandler); return this; } public ChannelPipeline addLast(String channelHandlerName,AbstactChannelHandler channelHandler){ if(org.apa