美文网首页
Apache commons-chain

Apache commons-chain

作者: 茶铺里的水 | 来源:发表于2018-01-19 10:42 被阅读799次

    在日常的工作中,我们经常会碰到一些业务流程比较复杂的场景,这些东西糅合到一个方法里就使得代码耦合度特别高,随着业务场景逻辑的越来越多,就会越来越复杂,难以维护。
    如提交的订单的动作可能涉及到如下场景:

    1. 各种各样的校验
    2. 各类信息的补充
    3. 订单提交成功/失败后产品信息/库存的改变
    4. 订单提交成功/失败后支付信息/状态的改变
    5. 订单提交成功/失败后的各种推送
    6. 等等

    还有一些更复杂的场景是要根据类型区分的,如不同的产品类型后续执行的动作是不一样的,假设某一类产品是不需要推送的,可能第5步就不需要

    项目中用过这么一个东西,Apache commons chain,原理是责任链模式。大致实现方式是根据不同的业务场景,建立多个Command,每个Command处理各自的业务逻辑,每个Command执行完毕后,将处理后的处理传给下一个Command,直到所有执行完毕。

    接口原理图

    代码实现

    1. 建立ChainBase,可以根据不同的应用场景建立多个ChainBase,如下示例我使用了1、2、3三个Command,当然我也可以根据需要只使用1和2
    package com.mk.chain;
    
    import com.mk.chain.commands.Commands1;
    import com.mk.chain.commands.Commands2;
    import com.mk.chain.commands.Commands3;
    import org.apache.commons.chain.Command;
    import org.apache.commons.chain.impl.ChainBase;
    
    public class CommandChain extends ChainBase{
        public CommandChain() {
            addCommand(new Commands1());
            addCommand(new Commands2());
            addCommand(new Commands3());
        }
    }
    
    1. 建立对应的Command,每个Command都是一个独立的类,需要实现Command接口

    Commands1.java

    package com.mk.chain.commands;
    
    import com.alibaba.fastjson.JSONObject;
    import io.swagger.models.auth.In;
    import org.apache.commons.chain.Command;
    import org.apache.commons.chain.Context;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    public class Commands1 implements Command{
    
        private static final Logger logger = LoggerFactory.getLogger(Commands1.class);
    
    
        @Override
        public boolean execute(Context context) throws Exception {
            Object v1 = context.get("k1");
            logger.info("do something by Commands1... params is {}", JSONObject.toJSONString(context));
            if(v1 != null){
                int IntV1 = (Integer) v1;
                context.put("k1", IntV1+1);
            }
            return false;
        }
    }
    

    Commands2.java

    package com.mk.chain.commands;
    
    import com.alibaba.fastjson.JSONObject;
    import org.apache.commons.chain.Command;
    import org.apache.commons.chain.Context;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    public class Commands2 implements Command{
    
        private static final Logger logger = LoggerFactory.getLogger(Commands2.class);
    
    
        @Override
        public boolean execute(Context context) throws Exception {
            Object v1 = context.get("k1");
            logger.info("do something by Commands2... params is {}", JSONObject.toJSONString(context));
            if(v1 != null){
                int IntV1 = (Integer) v1;
                context.put("k1", IntV1+1);
            }
            return false;
        }
    }
    

    Commands3.java

    package com.mk.chain.commands;
    
    import com.alibaba.fastjson.JSONObject;
    import org.apache.commons.chain.Command;
    import org.apache.commons.chain.Context;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    public class Commands3 implements Command{
    
        private static final Logger logger = LoggerFactory.getLogger(Commands3.class);
    
    
        @Override
        public boolean execute(Context context) throws Exception {
            Object v1 = context.get("k1");
            logger.info("do something by Commands3... params is {}", JSONObject.toJSONString(context));
            if(v1 != null){
                int IntV1 = (Integer) v1;
                context.put("k1", IntV1+1);
            }
            return false;
        }
    }
    
    1. 测试,建立测试类CommandTest.java
    package com.my.test;
    
    import com.mk.chain.CommandChain;
    import org.apache.commons.chain.Context;
    import org.apache.commons.chain.impl.ContextBase;
    import org.junit.Test;
    
    public class CommandTest {
    
        @Test
        public void test() throws Exception {
            CommandChain commandChain = new CommandChain();
            Context context = new ContextBase();
            context.put("k1",1);
            commandChain.execute(context);
        }
    }
    

    执行结果如下

    2018-01-19 10:20:54.356 [main] INFO  com.mk.chain.commands.Commands1 - do something by Commands1... params is {"k1":1}
    2018-01-19 10:20:54.363 [main] INFO  com.mk.chain.commands.Commands2 - do something by Commands2... params is {"k1":2}
    2018-01-19 10:20:54.363 [main] INFO  com.mk.chain.commands.Commands3 - do something by Commands3... params is {"k1":3}
    

    相关文章

      网友评论

          本文标题:Apache commons-chain

          本文链接:https://www.haomeiwen.com/subject/eshooxtx.html