(责任链模式)java可插拔式逻辑处理流程的实现

本文深入解析了责任链模式的概念、实现方式及应用实例,通过具体的代码示例展示了如何使用类Servlet的Filter实现逻辑处理流程的可插拔和独立维护,同时讨论了模式的优缺点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

关于责任链模式的学习资料

一、责任链模式的概念

【菜鸟教程】责任链模式

二、责任链模式的实现方式

【atheva】责任链模式实现的三种方式

这里采用了类servlet的Filter的实现方式,基本实现了逻辑处理流程在运行中的可插拔以及每个逻辑处理节点的独立维护

在责任链的不同节点中,使用k-v进行参数传递

public class ChainParam {
    private Map<ChainParamKeyEnum, Object> param = new ConcurrentHashMap<ChainParamKeyEnum, Object>();
    public static ChainParam newChainParam() {
        return new ChainParam();
    }
    public Object getParam(ChainParamKeyEnum key) {
        Object value = param.get(key);
        if (key.getClazz().isInstance(value)) {
            return value;
        }
        if (null != value) {
            throw new ClassCastException("get value is not type of clazz");
        }
        return null;
    }
    public Object putParam(ChainParamKeyEnum key, Object value) {
        if (null == value) {
            return null;
        }
        if (null != value && !key.getClazz().isInstance(value)) {
            throw new ClassCastException("put value is not type of clazz");
        }
        return param.put(key, value);
    }
    @Override
    public String toString() {
        return param.toString();
    }
}
public enum ChainParamKeyEnum {
    // dataInKey start
    DATA_IN_STRING(String.class),
    // dataInKey end
    // dataOutKey start
    DATA_OUT_STRING(String.class),
    // dataOutKey end
    // chainContextKey start
    CHAIN_CONTEXT_STRING(String.class)
    // chainContextKey end
    ;
    private Class<?> clazz;
    private ChainParamKeyEnum(Class<?> clazz) {
        this.clazz = clazz;
    }
    public Class<?> getClazz() {
        return this.clazz;
    }
}

责任链的实现框架

public interface Action {
    public void doChainAction(ChainParam dataIn, ChainParam dataOut, ChainParam chainContext, Chain chain);
}
public interface ChainNode<C, V> {
    C link(V t);
    C next();
    V nodeValue();
}
public class Chain implements Action, ChainNode<Chain, Action> {
    private static final Chain EOFChain = new Chain(null);
    private Chain nextChain;
    private final Action nodeAction;
    private Chain(Action nodeAction) {
        this.nodeAction = nodeAction;
        this.nextChain = EOFChain;
    }
    public static Chain newChain(Action nodeValue) {
        return new Chain(nodeValue);
    }
    @Override
    public Chain link(Action action) {
        Chain tNextChain = new Chain(action);
        this.nextChain = tNextChain;
        return tNextChain;
    }
    @Override
    public Chain next() {
        return this.nextChain;
    }
    @Override
    public Action nodeAction() {
        return this.nodeAction;
    }
    @Override
    public void doChainAction(ChainParam dataIn, ChainParam dataOut, ChainParam chainContext, Chain chain) {
        Action tAction = null;
        if (null == chain || null == (tAction = chain.nodeAction())) {
            return;
        }
        if (EOFChain == chain) {
            return;
        }
        tAction.doChainAction(dataIn, dataOut, chainContext, chain.next());
    }
}

责任链的处理节点编写

public class PrintDataIn implements Action {
    @Override
    public void doChainAction(ChainParam dataIn, ChainParam dataOut, ChainParam chainContext, Chain chain) {
        System.out.println(String.format("PrintDataIn print ChainParam dataIn:%s", dataIn));
        chain.doChainAction(dataIn, dataOut, chainContext, chain);
    }
}
public class GenerateDataOut implements Action {
    private static final ChainParamKeyEnum DATA_OUT_STRING = ChainParamKeyEnum.DATA_OUT_STRING;
    @Override
    public void doChainAction(ChainParam dataIn, ChainParam dataOut, ChainParam chainContext, Chain chain) {
        System.out.println(String.format("GenerateDataOut print ChainParam dataOut:%s", dataOut));
        System.out.println(String.format("GenerateDataOut generate ChainParam key:%s value:%s", DATA_OUT_STRING, "this is a dataOutValue"));
        dataOut.putParam(DATA_OUT_STRING, "this is a dataOutValue");
        chain.doChainAction(dataIn, dataOut, chainContext, chain);
    }
}
public class PrintChainContext implements Action {
    @Override
    public void doChainAction(ChainParam dataIn, ChainParam dataOut, ChainParam chainContext, Chain chain) {
        System.out.println(String.format("PrintChainContext print ChainParam chainContext:%s", chainContext));
        chain.doChainAction(dataIn, dataOut, chainContext, chain);
    }
}

将处理节点根据需要拼接成处理链条对dataIn进行处理,输出dataOut

public class Main {
    private static final ChainParamKeyEnum DATA_IN_STRING = ChainParamKeyEnum.DATA_IN_STRING;
    private static final ChainParamKeyEnum CHAIN_CONTEXT_STRING = ChainParamKeyEnum.CHAIN_CONTEXT_STRING;
    public static void main(String[] args) {
        // dataIn用于存储输入,dataOut用于存储链条中的处理输出,chainContext用于存储链条处理中的环境参数
        ChainParam dataIn = ChainParam.newChainParam();
        ChainParam dataOut = ChainParam.newChainParam();
        ChainParam chainContext = ChainParam.newChainParam();
        dataIn.putParam(DATA_IN_STRING, "this is a dataInValue");
        chainContext.putParam(CHAIN_CONTEXT_STRING, "this is a chainContextValue");
        // 拼装处理链条
        Chain chain = null;
        (chain = Chain.newChain(new PrintDataIn())).link(new GenerateDataOut()).link(new PrintChainContext());
        chain.doChainAction(dataIn, dataOut, chainContext, chain);
        // 获取处理结果dataOut
        System.out.println(String.format("chain action finish dataOut:%s", dataOut));
    }
}

缺点:

  1. 链条节点中参数的传递通过key-value形式,虽然比较灵活,但是当参数比较多时,会比较难维护
  2. 链条的处理是单向的,在处理过程中不可任意跳转

推荐:

  1. 将节点中用到的service(例如数据库操作)作为context中的参数传递进去
  2. 链条的生成使用工厂模式进行统一的管理
  3. 每个节点通过常量标记所使用到的dataIn,dataOut,chainContext参数的key
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值