一、定义
在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链。请求在这个链上传递,直到链上的某一个对象决定处理此请求。发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,这使得系统可以在不影响客户端的情况下动态地重新组织和分配责任,避免了请求发送者和接受者之间的耦合,但也同时降低了性能。
二、应用场景
申请活动费用的大致流程一般是,由申请人先填写申请单,然后交给领导审批,不同级别的领导,对于审批的额度是不一样的,比如,项目经理只能审批1000元以内的申请;部门经理能审批2000元以内的申请,而总经理可以审核任意额度的申请。
三、设计类图:
/**
* @Title: Handler.java
* @Description: 抽象处理者角色类
* @author: path
* @date: 2018/5/7 14:05
*/
public abstract class Handler {
/**
* 持有下一个处理请求的对象
*/
public Handler successor = null;
/**
* 取值方法
*/
public Handler getSuccessor() {
return successor;
}
/**
* 设置下一个处理请求的对象
*/
public void setSuccessor(Handler successor) {
this.successor = successor;
}
/**
* 处理活动费用的申请
*
* @param userName 申请人
* @param fee 申请的钱数
* @return String
*/
public abstract String handleFeeRequest(String userName, double fee);
}
/**
* @Title: ProjectManager.java
* @Description: 项目经理处理类
* @author: path
* @date: 2018/5/7 14:08
*/
public class ProjectManager extends Handler {
@Override
public String handleFeeRequest(String userName, double fee) {
String str = null;
//项目经理权限比较小,只能在1000以内
if (fee < 1000) {
str = "成功:项目经理同意【" + userName + "】的活动费用,金额为" + fee + "元";
} else {
//超过500,继续传递给级别更高的人处理
if (getSuccessor() != null) {
return getSuccessor().handleFeeRequest(userName, fee);
}
}
return str;
}
}
/**
* @Title: DeptManager.java
* @Description: 部门经理处理类
* @author: path
* @date: 2018/5/7 14:12
*/
public class DeptManager extends Handler {
@Override
public String handleFeeRequest(String user, double fee) {
String str = null;
//部门经理的权限只能在2000以内
if (fee < 2000) {
str = "成功:部门经理同意【" + user + "】的聚餐费用,金额为" + fee + "元";
} else {
//超过1000,继续传递给级别更高的人处理
if (getSuccessor() != null) {
return getSuccessor().handleFeeRequest(user, fee);
}
}
return str;
}
}
package com.path.blog.dutychain_model;
/**
* @Title: GeneralManager.java
* @Description: 总经理处理类
* @author: path
* @date: 2018/5/7 14:13
*/
public class GeneralManager extends Handler {
@Override
public String handleFeeRequest(String user, double fee) {
String str = null;
//总经理的权限很大,只要请求到了这里,他都可以处理
if (fee >= 2000) {
str = "成功:总经理同意【" + user + "】的聚餐费用,金额为" + fee + "元";
} else {
//如果还有后继的处理对象,继续传递
if (getSuccessor() != null) {
return getSuccessor().handleFeeRequest(user, fee);
}
}
return str;
}
}
package com.path.blog.dutychain_model;
/**
* @Title: ClientTest.java
* @Description: 职责链测试类
* @author: path
* @date: 2018/5/7 14:15
*/
public class ClientTest {
public static void main(String[] args) {
//先要组装责任链
Handler h1 = new GeneralManager();
Handler h2 = new DeptManager();
Handler h3 = new ProjectManager();
h3.setSuccessor(h2);
h2.setSuccessor(h1);
//开始测试
String test1 = h3.handleFeeRequest("张三", 500);
System.out.println("test1 = " + test1);
String test3 = h3.handleFeeRequest("张三", 1500);
System.out.println("test2 = " + test3);
String test5 = h3.handleFeeRequest("张三", 2500);
System.out.println("test3 = " + test5);
}
}
四、职责链模式的优缺点
优点:
1)降低耦合度,客户端不需要知道请求由哪个处理者处理,而处理者也不需要知道处理者之间的传递关系,由系统灵活的组织和分配。
2)良好的扩展性,增加处理者的实现很简单,只需重写处理请求业务逻辑的方法。
缺点:
1)请求会从链头发出,直到有处理者响应,在责任链比较长的时候会影响系统性能。
2)请求递归,调试排错比较麻烦。