概述
责任链模式(Chain of Responsibility Pattern)属于行为型设计模式。它为请求创建了一个处理链条,这个链条上的所有对象都要对这个请求进行处理。比如我们生活中经常使用的审批流程,当每一个节点审批通过后,发送给下一个节点,如:开发小组长->部门领导->总经理。也可以和java中的链表进行类比。
使用场景
- 当一个请求需要进行一系列的处理的时候,如:数据处理过程需要进行数据抽取、清洗、转换、存储
如何实现
以审批流程为例,如何进行抽象设计:
- 所有对象都具有审批行为,将其作为一个抽象方法doApproval()
- 所有对象都具有传递行为,将需要审批的单据传递给下一个审批人。而传递的逻辑都是一样的,所以将传递行为定义为一个默认的方法delivery()
- 既然需要传递,那么就要知道下一个审批人是谁。所以将下一个审批人作为一个成员属性
代码示例
/**
* 审批人抽象
*/
public abstract class Approver {
private Approver nextApprover;
/**
* 审批逻辑
* @param money
*/
abstract void doApproval(int money);
/**
* 责任链传递方法
* @param money
*/
protected void delivery(int money) {
if (nextApprover == null) {
System.out.println("结束::没有下一个审批人了");
} else {
nextApprover.doApproval(money);
}
}
public Approver getNextApprover() {
return nextApprover;
}
public void setNextApprover(Approver nextApprover) {
this.nextApprover = nextApprover;
}
}
/**
* 小组长审批实现
*/
public class TeamLeaderApprover extends Approver {
@Override
public void doApproval(int money) {
if (money <= 5000) {
System.out.println("TeamLeader::审批通过::交给下一个审批人");
} else {
System.out.println("TeamLeader::没有权限::交给下一个审批人");
}
this.delivery(money);
}
}
/**
* 部门领导审批实现
*/
public class DeptLeaderApprover extends Approver {
@Override
public void doApproval(int money) {
if (money <= 10000) {
System.out.println("DeptLeader::审批通过::交给下一个审批人");
} else {
System.out.println("DeptLeader::没有权限::交给下一个审批人");
}
this.delivery(money);
}
}
/**
* CEO审批实现
*/
public class CEOApprover extends Approver {
@Override
public void doApproval(int money) {
if (money <= 20000) {
System.out.println("CEO::这么点钱用不着审批::交给下一个审批人");
} else {
System.out.println("CEO::审批通过::交给下一个审批人");
}
this.delivery(money);
}
}
/**
* 测试
*/
public class ChainTest {
public static void main(String[] args) {
TeamLeaderApprover teamLeaderApprover = new TeamLeaderApprover();
DeptLeaderApprover deptLeaderApprover = new DeptLeaderApprover();
CEOApprover ceoApprover = new CEOApprover();
//给当前审批人设置下一个审批人
teamLeaderApprover.setNextApprover(deptLeaderApprover);
deptLeaderApprover.setNextApprover(ceoApprover);
//执行审批行为,自动传递
teamLeaderApprover.doApproval(10000);
}
}
运行结果
TeamLeader::没有权限::交给下一个审批人
DeptLeader::审批通过::交给下一个审批人
CEO::这么点钱用不着审批::交给下一个审批人
结束::没有下一个审批人了
框架源码中的应用
- javax.servlet包中的Filter接口
总结
优点
- 将请求发送者和接受者解耦
- 增加新的请求处理类很方便
- 可以灵活的安排链条中每个节点的顺序或删除某一个节点
缺点
- 当链条过长时会对系统性能造成一定影响
- 不能保证请求一定被接收,因为请求发送过去之后没有反馈