优雅使用责任链模式

前言

好的设计可以让业务的开发和扩展更加的方便和风险更小,责任链设计模式是常见的结构设计,本文不介绍设计模式的基本概念和责任链模式的基本结构,主要思考责任链模式的优化思路。


责任链模式就是能够把请求与处理请求的handler给解耦。
| handler1 | -> |handler2| -> |handler3|
图1
这样一种结构,好处就是能够让请求的调用只关心请求的提交,不用关心任务的处理。
这里有一个问题,这里需要去严格的指定调用请求的顺序,这在某些情况是必要的,在某些情况能够中断后置处理,这在某些情况也是合理的。
一个代码示范:

/**
 * 处理请求的类
 */
interface Handler {

    /**
     * 处理请求
     * @param params
     */
    void process(Object params);

}

/**
 * chain模板实现
 */
abstract class HandlerChain implements Handler {

    protected Handler handler;

    public void setNext(Handler handler) {
        this.handler = handler;
    }

    /**
     * 串行处理
     * @param params
     */
    @Override
    public void process(Object params) {
        subProcess(params);
        if (handler != null) {
            handler.process(params);
        }
    }

    /**
     * 真实处理
     * @param params
     */
    protected abstract void subProcess(Object params);

}

class IntergerHandler extends HandlerChain {
    @Override
    public void subProcess(Object params) {
        if (params instanceof Integer) {
            System.out.println("integer processed");
        }
    }
}

class StringHandler extends HandlerChain {
    @Override
    public void subProcess(Object params) {
        if (params instanceof String) {
            System.out.println("string processed");
        }
    }
}

class HandlerContext {

    /**
     * 维护串行关系
     * @return
     */
    Handler initHandler() {
        IntergerHandler intergerHandler = new IntergerHandler();
        StringHandler stringHandler = new StringHandler();

        intergerHandler.setNext(stringHandler);

        return intergerHandler;
    }

    /**
     * 调用请求
     * @param request
     */
    void subRequest(Object request) {
        initHandler().process(request);
    }

}

这里有个不太好的地方就是增加一个扩展不仅需要去继承,还需要去维护iniHandler,如果是Spring直接注入。会更加的方便.
但是也有这样一种场景,不关心调用顺序,不想去维护

/**
     * Spring注入
     * @return
     */

    @Resource
    private List<HandlerChain> handlerChainList;

    /**
     * 调用请求
     * @param request
     */
    void subRequest(Object request) {
        handlerChainList.forEach(handlerChain -> handlerChain.process(request));
    }

这样优雅多了,但是我们写完了发现扩展一个实现就干两件事情。

  1. 判断该请求自己该不该处理
  2. 如果不处理,直接忽视.
    所以有个固定的, 就如示范里的:
    if (params instanceof …)
    这种模版化的代码可以进行抽象.
/**
 * chain模板实现
 */
abstract class HandlerChain implements Handler {

    protected Handler handler;

    public void setNext(Handler handler) {
        this.handler = handler;
    }

    /**
     * 串行处理
     * @param params
     */
    @Override
    public void process(Object params) {
        if (!match(params)) {
        	return ;
        }
        subProcess(params);
    }

    /**
     * 真实处理
     * @param params
     */
    protected abstract void subProcess(Object params);

    /**
     * 是否该handler处理
     * @param params
     * @return
     */
    protected abstract boolean match(Object params);

}

class IntergerHandler extends HandlerChain {
    @Override
    public void subProcess(Object params) {
        System.out.println("integer processed");

    }

    @Override
    protected boolean match(Object params) {
        return params instanceof Integer;
    }
}

class StringHandler extends HandlerChain {
    @Override
    public void subProcess(Object params) {
        System.out.println("string processed");
    }

    @Override
    protected boolean match(Object params) {
        return params instanceof String;
    }
}

class HandlerContext {

    /**
     * Spring注入
     * @return
     */

    @Resource
    private List<HandlerChain> handlerChainList;

    /**
     * 调用请求
     * @param request
     */
    void subRequest(Object request) {
        handlerChainList.forEach(handlerChain -> handlerChain.process(request));
    }
}

这样去扩展handler只需要写两个东西,match和process逻辑。不用再关心调用的串行,也有效的规避了修改现有代码的风险,满足了开闭原则。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值