首先我们来看一个例子,在一个人员众多大公司里,为了方便人员管理,自然形成了金字塔结构的管理层级,最上层是老板,最底层为苦逼的码农,中间则是各个等级的管理层,并且无法跨层管理,也就是你只能与上级或者下级进行沟通,每个管理层的权限都是不一样的,逐级向上递增;现在一个员工要请半个月的假,组长最多能批3天假,于是这个申请由组长递交到项目经理,项目经理只能批5天内的假,项目经理就把这个申请递交到部门经理,部门经理只能批10天内的假,最后部门经理把申请递交到老板那里由老板决定,老板的决定再一层层向下传递到申请假期的员工那;如果员工只申请3天的假,那组长就可以直接决定,这个申请也不会向上递交了。
从上面这个例子,可以看出:
1)员工申请的流程很简单,不用知道谁可以批这个申请,只要向他的上级组长递交申请就可以了。
2)这个申请被批了后就不用再继续向上递交了。
这就是典型的责任链模式。
定义:将若干对象按照某种层级结构组织为链状,没个对象决定他能处理那些命令,也知道如何将不能处理的命令传递给链中的下一个对象。客户端调用处于链首对象的处理方法,对象要么执行该方法,要么沿着这条链将方法请求转发到下一个对象。责任链模式让每个对象都有一次机会决定自己是否处理请求,避免了请求的发送者和接收者之间的耦合。
结构:
- 抽象处理类:主要包含一个指向下一个处理类的成员变量nextHandler和一个处理请求的方法handRequest,该方法的主要思想是,如果满足处理的条件,则由本处理类来进行处理,否则转发到nextHandler。
- 具体处理类:主要是对具体的处理逻辑和处理的适用条件进行实现。
适用场景:
- 有多个对象可以处理一个请求,那个对象处理该请求运行时刻自动确定
- 你想在不明确指定接收者的情况下,想多个对象中的一个提交一个请求
UML:
下面是代码的实现:
RequestHandler
public abstract class RequestHandler {
protected RequestHandler nextHandler=null;
protected int level;
abstract Response handleRequese(Request request);
protected Response goNextHandler(Request request){
Response r = new Response();
if(nextHandler==null){
r.responseContent="没有对象能处理该请求";
return r;
}else{
return nextHandler.handleRequese(request);
}
}
}
ConcreteRequestHandler1,2,3…除了level不一样,其他的代码都是一样(因为这里只是演示,所有每个处理类的处理逻辑是一样的,显示开发中处理类的逻辑可能是不应的,根据具体情况而定)。
ConcreteRequestHandler1:
public class ConcreteRequestHandler1 extends RequestHandler{
public ConcreteRequestHandler1(RequestHandler requestHandler) {
// TODO Auto-generated constructor stub
this.level=1;
this.nextHandler = requestHandler;
}
@Override
Response handleRequese(Request request) {
if(request.level==this.level){
// TODO 对request一顿处理
Response response = new Response();
response.responseContent = "这是"+this.getClass().getName()+"处理的结果";
return response;
}else{
return goNextHandler(request);
}
}
}
Request:
public class Request {
int level;
}
Response:
public class Response {
String responseContent;
}
测试类:
public class Test {
public static void main(String[] args){
Request r = new Request();
r.level = 2;
RequestHandler chainHead = new ConcreteRequestHandler1
(new ConcreteRequestHandler2(new ConcreteRequestHandler3(null)));
Response response =chainHead.handleRequese(r);
System.out.println(response.responseContent);
}
}
总结:
责任链模式其实就是一个灵活版的if…else…语句,只是将这些判断语句放到了各个处理类中。这样做的优点就是比较灵活,便于扩展,当要增加一个新的处理类时,只要把链尾处理类的nextHandler指向新的处理类就可以了;也可以插入到链中部的,读者稍微思考就知道怎么做了。要注意的是,处理类前后的顺序和逻辑判断一定要搞清楚,并且不要再链中出现循环引用。
参考:http://wiki.jikexueyuan.com/project/java-design-pattern/chain-responsibility-pattern.html
http://www.cnblogs.com/java-my-life/archive/2012/05/28/2516865.html