前言
好的设计可以让业务的开发和扩展更加的方便和风险更小,责任链设计模式是常见的结构设计,本文不介绍设计模式的基本概念和责任链模式的基本结构,主要思考责任链模式的优化思路。
责任链模式就是能够把请求与处理请求的handler给解耦。
| handler1 | -> |handler2| -> |handler3|
这样一种结构,好处就是能够让请求的调用只关心请求的提交,不用关心任务的处理。
这里有一个问题,这里需要去严格的指定调用请求的顺序,这在某些情况是必要的,在某些情况能够中断后置处理,这在某些情况也是合理的。
一个代码示范:
/**
* 处理请求的类
*/
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));
}
这样优雅多了,但是我们写完了发现扩展一个实现就干两件事情。
- 判断该请求自己该不该处理
- 如果不处理,直接忽视.
所以有个固定的, 就如示范里的:
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逻辑。不用再关心调用的串行,也有效的规避了修改现有代码的风险,满足了开闭原则。