【小威哥の设计模式系列-6】管道模式/责任链模式

5,456 阅读3分钟

1:概述

都好久没有写设计模式了,今天小威哥就讲讲所有设计模式里面我最喜欢,也是最最最最!!实用的模式---管道模式/责任链模式


2:管道和责任链

管道模式和责任链模式其实非常像,只是一些概念的细节上有点区别,所以这边就一起讲了

  • 管道模式:大家就想象这是一个水管,里面有很多处理器,我们的请求像水流一样经过处理器去执行请求
  • 责任链模式:无非就是每个处理器去处理自己特定的请求,价格if判断的事


3:直接上代码

3.1:我们需要构造一个储存上下文(Context)的类

这里的上下文可以是request,也可以是response,甚至可以是一些状态啊什么的,随便自己定义,表示的是这次请求的生命周期

public class ChainBaseContext {

    /**
     * 是否继续传递
     */
    private boolean isContinue;

    /**
     * 统计经过处理的处理器数目
     **/
    private int chainCount = 0;
    
    private String request;
    private String response;

    public boolean isContinue() {
        return isContinue;
    }

    public void setContinue(boolean aContinue) {
        isContinue = aContinue;
    }

    public int getChainCount() {
        return chainCount;
    }

    public void setChainCount(int chainCount) {
        this.chainCount = chainCount;
    }
}

3.2:然后我们需要定义好我们的处理器

//这是api 接口
public interface ChainApi<C extends ChainBaseContext> {

    /**
     * 执行处理
     */
    void deal(C context);
}
public class HouseFitUpHandler implements ChainApi {
    @Override
    public void deal(ChainBaseContext context) {
        System.out.println("房子已经装修完成");
    }
}
public class MakeHouseHandler implements ChainApi {
    @Override
    public void deal(ChainBaseContext context) {
        if (true) {
            //执行器里面可以根据context的条件判断是否要执行
        }
        System.out.println("房子造好了");
    }
}

如果你的处理器是无状态的(没有成员变量这种东西),处理器可以定义成单例(netty管道就可以用一个注解来定义单例handler)

3.3:就下来我们就写一个核心责任链处理类

public class CoreChain {
    private ChainBaseContext context;

    private List<ChainApi> handles = Lists.newArrayList();

    private List<ChainApi> coreHandles = Lists.newArrayList();

    public CoreChain(ChainBaseContext context) {
        this.context = context;
    }

    @SuppressWarnings("unchecked")
    public void doHandle() {
        try {
            //执行一般的处理器,这里可以是前置处理器啊什么的
            for (ChainApi chainApi : handles) {
                //这里可以加个判断条件,可以中断传递
                if (!context.isContinue()) {
                    break;
                }
                chainApi.deal(context);
            }
            try {
                //这里执行核心逻辑,除了问题执行回滚逻辑
                for (ChainApi chainApi : coreHandles) {
                    chainApi.deal(context);
                }
            } catch (Exception e) {
                //执行回滚这里
            }

        } catch (Exception e) {
            //do something
        }
    }


    public void setCoreHandles(List<ChainApi> coreHandles) {
        this.coreHandles = coreHandles;
    }

    public void setHandles(List<ChainApi> handles) {
        this.handles = handles;
    }

}

3.4:最后我们就可以写一个demo来测试下就好了

    public static void main(String[] args) {
        CoreChain coreChain = new CoreChain(new HouseMakeContext());
        List<ChainApi> apis = Lists.newArrayList();
        List<ChainApi> coreApis = Lists.newArrayList();
        apis.add(new MakeHouseHandler());
        coreApis.add(new HouseFitUpHandler());
        coreChain.setHandles(apis);
        coreChain.setCoreHandles(coreApis);
        //到这里我们的责任链或者所谓的pipline构造完成了
        //我们真正去执行
        coreChain.doHandle();
    }

4:总结

上述的demo只是一个责任链或者管道最简单的形式,我们可以根据自己的需求随意定制里面的流程啊,控制啊!非常棒!我一直觉得这个模式就是java设计模式的精髓所在了!!!把一个很冗长的处理流程拆分成一个个小的逻辑执行器,强力推荐。