责任链模式的设计思想,在于采用“链传递”的模式,将同一类请求,交由一条“责任链”上的多个功能模块进行处理,每个功能模块作为责任链上的一环,请求在链上按照既定顺序依次传递,直到找到一个能够处理该请求的功能模块。在这种模式下,我们能够迅速的在一条责任链中扩展出新的环,从而适应项目对同一类请求的新的处理要求。一种典型的应用环境是,对web应用,通常有VIP用户和普通用户的注册请求,其实这同属于一种请求,只不过是VIP注册可能会多一个字段邀请码什么的,我们不需要单独为每一种请求写一个controller,而是可以在同一个controller中,通过将该请求传递到一个包含处理普通用户以及VIP用户注册请求的“责任链”上进行统一处理。从而精简项目结构。当然,这只是一种举例,分开写controller可能结构更清晰。
首先,列出一个典型的责任链模式设计类图:
上述类图中,需要关注的是Handler类,它作为责任链的“环”的抽象超类,其中定义了一个final方法handler(),它实现的功能是,保证链上的每一环都必须响应传到该链上的请求,而对请求的具体处理方式echo()函数由各子类去实现,它还包含一个Handler类型的nextHandler私有变量,它定义了该链的下一环。Handler1和Handler2是Handler类的子类,实现了具体环的功能逻辑。另外,Request和Response类是用于定义请求以及回复消息的协议规范,Level类标识了一个Request能够被哪一个Handler类处理。通过匹配自身的Level与请求的Level,链上的环知道自己是该拦截请求进行处理还是交由下一环继续处理。其具体代码如下:
Handler.java
/**
* Created by Song on 2016/10/23.
* 抽象处理者
*/
public abstract class Handler {
private Handler nextHandler; //责任链的下一环
//每一环责任链都必须对请求作出处理
public final Response handler(Request request){
Response response = null;
//判断请求级别是否是自己所处理的
if(request.getRequestLevel().equals(this.getHandlerLever())) response=this.echo(request);
else{
//存在下一环
if(null != this.nextHandler){
response=this.nextHandler.echo(request);
}else{
//TO-DO
}
}
return response;
}
//设置自己的下一环
public void setNextHandler(Handler nextHandler) {
this.nextHandler = nextHandler;
}
//获取自己所处理消息的等级
public abstract Level getHandlerLever();
//具体处理方式
public abstract Response echo(Request request);
}
Handler1.java
/**
* Created by Song on 2016/10/23.
* 具体责任链上的一环
*/
public class Handler1 extends Handler {
@Override
public Level getHandlerLever() {
return Level.ONE;
}
@Override
public Response echo(Request request) {
return new Response();
}
}
Handler2.java
/**
* Created by Song on 2016/10/23.
* 责任链上的具体一环
*/
public class Handler2 extends Handler {
@Override
public Level getHandlerLever() {
return Level.TWO;
}
@Override
public Response echo(Request request) {
return new Response();
}
}
Level.java
/**
* Created by Song on 2016/10/23.
* 事件等级
*/
public enum Level {
ONE,TWO,THREE,FOUR
}
Request.java
public class Request {
//请求待处理的类型
private final Level level;
//封装的请求数据
private Map<Object,Object> data = new HashMap<Object, Object>();
public Request(Level level,Map<Object,Object> data){
this.level = level;
this.data = data;
}
public Level getRequestLevel(){
return this.level;
}
public Map<Object,Object> getRequestData(){
return this.data;
}
}
Response.java
/**
* Created by Song on 2016/10/23.
* 处理者返回的数据,也可以定义为接口,通过继承实现对不同回复数据的封装
*/
public class Response {
}
Client.java:测试类
/**
* Created by Song on 2016/10/23.
* 责任链模式
*/
public class Client {
public static void main(String [] args){
//构建责任链
Handler handler1 = new Handler1();
Handler handler2 = new Handler2();
handler1.setNextHandler(handler2);
//模拟构建请求
Map<Object,Object> map = new HashMap<Object, Object>();
map.put("name","Mary");
Request request = new Request(Level.TWO,map);
//将请求交给责任链响应,并获得处理结果
Response response = handler1.handler(request);
//TO-DO
}
}