模式动机
责任链是指一系列的结点连接在一起形成一条链,每个节点有各自的职责。链可以是一条直线、一个环或者一个树形结构,最常见的职责链是直线型,即沿着一条单向的链来传递请求。链上的每一个结点都是请求处理者,职责链模式可以将请求的处理者组织成一条链,并使请求沿着链传递,由链上的处理者对请求进行相应的处理,客户端无须关心请求的处理细节以及请求的传递,只需将请求发送到链上即可。责任链模式的目的就是将请求的发送者和请求的处理者解耦。
模式定义
避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止。
模式结构
抽象处理类:Handler,定义一个处理请求的接口
具体处理类:ConcreteHandler,具体的处理类
代码示例
请假是一个生活中经常会碰到的问题,假设这样一个场景,某公司的请假制度如下:如果请假天数在两天之内,则A领导可以处理、审批,决定是否准假。如果是三天至五天,那么则需要让B领导来定夺,决定是否准假。如果请假天数超过五天,那必须由C领导进行审批。代码如下:
//抽象处理类
public abstract class Leader {
protected Leader nextHandler;
public abstract void handleRequest(LeaveRequest request);
public Leader getNextHandler() {
return nextHandler;
}
public void setNextHandler(Leader nextHandler) {
this.nextHandler = nextHandler;
}
}
//具体处理类
public class LeaderA extends Leader{
@Override
public void handleRequest(LeaveRequest request) {
if(request.getDays()<=2){
System.out.println("请假天数在2天之内,A领导处理此假条");
}else{
if(this.nextHandler!=null)
{
this.nextHandler.handleRequest(request);
}
}
}
}
public class LeaderB extends Leader{
@Override
public void handleRequest(LeaveRequest request) {
if( 6 <= request.getDays()){
System.out.println("请假天数在3至5天,B领导处理此假条");
}else{
if(this.nextHandler!=null)
{
this.nextHandler.handleRequest(request);
}
}
}
}
public class LeaderC extends Leader{
@Override
public void handleRequest(LeaveRequest request) {
if( 3 <= request.getDays() && request.getDays()<=5){
System.out.println("请假天数超过5天,C领导处理此假条");
}else{
if(this.nextHandler!=null)
{
this.nextHandler.handleRequest(request);
}
}
}
}
//请求者
public class LeaveRequest
{
private int days;//请假天数
public int getDays() {
return days;
}
public void setDays(int days) {
this.days = days;
}
}
public class Client {
public static void main(String[] args) {
Leader a = new LeaderA();
Leader b = new LeaderB();
Leader c = new LeaderC();
a.setNextHandler(b);
b.setNextHandler(c);
LeaveRequest r1 = new LeaveRequest();
r1.setDays(1);
a.handleRequest(r1);//请假天数在2天之内,A领导处理此假条
LeaveRequest r2 = new LeaveRequest();
r2.setDays(4);
a.handleRequest(r2);//请假天数在3至5天,B领导处理此假条
LeaveRequest r3 = new LeaveRequest();
r3.setDays(7);
a.handleRequest(r3);//请假天数超过5天,C领导处理此假条
}
}
总结
责任链模式使得客户端并不需要知道链上的哪一个对象最终处理这个请求,这使得系统可以在不影响客户端的情况下动态地重新组织链和分配责任。降低了系统的耦合度。同时新增或删除一个具体处理类结点也非常方便,增强了灵活性。