职责链模式
职责链模式是一种行为设计模式, 允许你将请求沿着处理者链进行发送。 收到请求后, 每个处理者均可对请求进行处理, 或将其传递给链上的下个处理者。
职责链模式通常每个接收者都包含对另一个接收者的引用。如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依此类推。
责任链将请求的发送者和请求的处理者解耦了。
概括:把请求从链中的一个对象传到下一个对象,直到请求被响应为止。通过这种方式去除对象之间的耦合。
职责链模式存在以下两种情况。
- 纯的职责链模式:一个请求必须被某一个处理者对象所接收,且一个具体处理者对某个请求的处理只能采用以下两种行为之一:自己处理(承担责任);把责任推给下家处理。
- 不纯的职责链模式:允许出现某一个具体处理者对象在承担了请求的一部分责任后又将剩余的责任传给下家的情况,且一个请求可以最终不被任何接收端对象所接收。
模式结构
- Handler : 抽象的处理者, 定义了一个处理请求的接口, 同时含义另外Handler
- ConcreteHandlerA , B 是具体的处理者, 处理它自己负责的请求, 可以访问它的后继者(即下一个处理者), 如果可以处理当前请求,则处理,否则就将该请求交个 后继者去处理,从而形成一个职责链
- Request:含义很多属性,表示一个请求。
类图
优缺点
优点:
- 降低了对象之间的耦合度。该模式使得一个对象无须知道到底是哪一个对象处理其请求以及链的结构,发送者和接收者也无须拥有对方的明确信息。
- 单一职责原则。 你可对发起操作和执行操作的类进行解耦。
- 开闭原则。 你可以在不更改现有代码的情况下在程序中新增处理者,增强了系统的可扩展性。
- 责任链简化了对象之间的连接。每个对象只需保持一个指向其后继者的引用,不需保持其他所有处理者的引用,这避免了使用众多的 if 或者 if···else 语句。
- 增强了给对象指派职责的灵活性。当工作流程发生变化,可以动态地改变链内的成员或者调动它们的次序,也可动态地新增或者删除责任。
缺点:
- 部分请求可能未被处理。
- 如果职责链比较长,请求的处理可能涉及多个处理对象,系统性能将受到一定影响。
- 职责链建立的合理性要靠客户端来保证,增加了客户端的复杂性。
SpringMVC 中的职责链模式
职责链模式在SpringMVC-HandlerExecutionChain 类就使用到职责链模式。
springmvc 请求的流程图中,执行了拦截器相关方法 interceptor.preHandler 等等
-
- 在处理SpringMvc请求时,使用到职责链模式还使用到适配器模式
-
- HandlerExecutionChain 主要负责的是请求拦截器的执行和请求处理,但是他本身不处理请求,只是将请求分配给链上注册处理器执行,这是职责链实现方式,减少职责链本身与处理逻辑之间的耦合,规范了处理流程
-
- HandlerExecutionChain 维护了 HandlerInterceptor 的集合,可以向其中注册相应的拦截器.
- HandlerExecutionChain 维护了 HandlerInterceptor 的集合,可以向其中注册相应的拦截器.
应用场景
- 多个对象可以处理一个请求,但具体由哪个对象处理该请求在运行时自动确定。
- 当必须按顺序执行多个处理者时, 可以使用职责链模式。
- 如果所需处理者及其顺序必须在运行时进行改变, 可以使用职责链模式。
- 需要动态指定一组对象处理请求,或添加新的处理者。
- 需要在不明确指定请求处理者的情况下,向多个处理者中的一个提交请求。
示例代码
学校OA系统的采购审批流程
public abstract class ApprovalHandle {
protected ApprovalHandle approvalHandle;
protected String approvalName;
public ApprovalHandle(String approvalName){
this.approvalName = approvalName;
}
protected void setApproval(ApprovalHandle approvalHandle){
this.approvalHandle = approvalHandle;
}
protected abstract void handleRequest(PurchaseRequest request);
}
public class ChainOfResponsibilityPattern {
public static void main(String[] args) {
PurchaseRequest request = new PurchaseRequest(1,8000);
ApprovalHandle classApproval = new ClassApproval("班主任");
ApprovalHandle departmentApproval = new DepartmentApproval("系主任");
ApprovalHandle deanApproval = new DeanApproval("院主任");
ApprovalHandle masterApproval = new MasterApproval("校主任");
classApproval.setApproval(departmentApproval);
departmentApproval.setApproval(deanApproval);
deanApproval.setApproval(masterApproval);
masterApproval.setApproval(classApproval);
classApproval.handleRequest(request);
}
}
public class ClassApproval extends ApprovalHandle {
public ClassApproval(String approvalName) {
super(approvalName);
}
@Override
protected void handleRequest(PurchaseRequest request) {
if (request.getPrice() <= 5000){
System.out.println("编号为"+request.getId()+"的请求由"+approvalName + "来处理");
}
else if (approvalHandle != null){
approvalHandle.handleRequest(request);
}
else System.out.println("没人愿意处理");
}
}
public class DeanApproval extends ApprovalHandle{
public DeanApproval(String approvalName) {
super(approvalName);
}
@Override
protected void handleRequest(PurchaseRequest request) {
if (request.getPrice() > 10000 && request.getPrice() <= 30000){
System.out.println("编号为"+request.getId()+"的请求由"+approvalName + "来处理");
}
else if (approvalHandle != null){
approvalHandle.handleRequest(request);
}
else System.out.println("没人愿意处理");
}
}
public class DepartmentApproval extends ApprovalHandle{
public DepartmentApproval(String approvalName) {
super(approvalName);
}
@Override
protected void handleRequest(PurchaseRequest request) {
if (request.getPrice() > 5000 && request.getPrice() <= 10000){
System.out.println("编号为"+request.getId()+"的请求由"+approvalName + "来处理");
}
else if (approvalHandle != null){
approvalHandle.handleRequest(request);
}
else System.out.println("没人愿意处理");
}
}
public class MasterApproval extends ApprovalHandle{
public MasterApproval(String approvalName) {
super(approvalName);
}
@Override
protected void handleRequest(PurchaseRequest request) {
if (request.getPrice() > 30000 ){
System.out.println("编号为"+request.getId()+"的请求由"+approvalName + "来处理");
}
else if (approvalHandle != null){
approvalHandle.handleRequest(request);
}
else System.out.println("没人愿意处理");
}
}
public class PurchaseRequest {
private int price;
private int id;
public PurchaseRequest(int id ,int price) {
this.id = id;
this.price = price;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}