什么是责任链模式
个人理解责任链模式就是当有多个接收者对象可以处理同一个请求的时候,为所有可以处理请求的接收者对象创建一个的有顺序的权力链,并且按照权力的大小来决定顺序的前后,从而避免了请求者和接收者直接的耦合关系,链上的每个接收者对象都包含者对下一个接收者对象的引用,也就是说,如果一个接收者未对请求进行处理,它就会把这个请求传送给下一个权力更大的接收者,直到有一个对象处理它为止。
案例
在高校中,报账报批流程是:申请人提交审批文件–学院管理部门审批(金额小于等于10000)—学校管理部门审审批(金额小于等于30000)—校长审批(金额小于等于50000)—校常委办公会审批(金额小于等于100000)—教育局审批(金额超过100000以上)。需要设计程序完成报账报批流程。
对照传统的方案
想要学习一个设计模式,首要的就是了解这个设计模式解决什么。当我们没有学习责任链模式的时候,我们就会采用这样的方案:
在传统的方式总我们通常会根据金额的多少使用if语句或者是switch语句去调用不同的接收者完成审批。这样会很简单,但是也会有一些问题。
- 当不同接收者的权限发生变化的时候,客户端也需要发生变化。
- 客户端必须知道有多少个接收者,并且添加它们。
我们可以发现在传统的方案中请求者和接收者存在一个强的耦合关系,这不利于代码的拓展与维护,所以我们就引进了责任链模式去解决这些问题。
责任链模式的类图
- Request类表示一个请求
- Handler类是一个抽象的接收者,定义了一个处理请求的接口,聚合了另外的 Handler
- CollegeManageHandler等类是具体的接收者,负责处理它权限内的请求或者将请求转交给它的后继者。
- Client类指客户端
责任链模式的代码
请求类Request
package responsibilityChain;
//请求类
public class Request {
private int price = 0 ;
//构造器
public Request(int price) {
this.price = price;
}
public int getPrice() {
return price;
}
}
抽象的接收者Handler
package responsibilityChain;
//抽象的接收者,定义了一个处理请求的接口,聚合另外的 Handler
public abstract class Handler {
Handler handler;//下一个接收者
//构造下一个接收者
public void setHandler(Handler handler) {
this.handler = handler;
}
//定义一个处理请求的方法具体实现交给子类
public abstract void processRequest(Request request);
}
学院接收者CollegeManageHandler
package responsibilityChain;
//学院接收者
public class CollegeManageHandler extends Handler{
@Override
public void processRequest(Request request) {
// TODO Auto-generated method stub
if (request.getPrice()<10000) {
System.out.println("学院管理部门同意了你的审批");
} else {
System.out.println("学院管理部门转交下一级审批");
handler.processRequest(request);
}
}
}
学校接收者UniversityManageHandler
package responsibilityChain;
//学校接收者
public class UniversityManageHandler extends Handler{
@Override
public void processRequest(Request request) {
// TODO Auto-generated method stub
if (request.getPrice()<30000) {
System.out.println("学校管理部门同意了你的审批");
} else {
System.out.println("学校管理部门转交下一级审批");
handler.processRequest(request);
}
}
}
校长接收者PrincipalHandler
package responsibilityChain;
//校长接收者
public class PrincipalHandler extends Handler{
@Override
public void processRequest(Request request) {
// TODO Auto-generated method stub
if (request.getPrice()<50000) {
System.out.println("校长同意了你的审批");
} else {
System.out.println("校长转交下一级审批");
handler.processRequest(request);
}
}
}
校常委接收者SchoolstandingCommitteeHandler
package responsibilityChain;
//校常委接收者
public class SchoolstandingCommitteeHandler extends Handler{
@Override
public void processRequest(Request request) {
// TODO Auto-generated method stub
if (request.getPrice()<100000) {
System.out.println("校常委办公室同意了你的审批");
} else {
System.out.println("校常委办公室转交下一级审批");
handler.processRequest(request);
}
}
}
教育部接收者EducationBureauHandler
package responsibilityChain;
//教育部接收者
public class EducationBureauHandler extends Handler{
@Override
public void processRequest(Request request) {
// TODO Auto-generated method stub
if (request.getPrice()>100000) {
System.out.println("教育部同意了你的审批");
} else {
System.out.println("你的申请被拒绝");
}
}
}
客户端Client
package responsibilityChain;
public class Client {
public static void main(String[] args) {
// TODO Auto-generated method stub
//创建一个请求
Request request = new Request(200000);
//设置各个接收者的下一级别
CollegeManageHandler collegeManageHandler = new CollegeManageHandler();
UniversityManageHandler universityManageHandler = new UniversityManageHandler();
PrincipalHandler principalHandler = new PrincipalHandler();
SchoolstandingCommitteeHandler schoolstandingCommitteeHandler = new SchoolstandingCommitteeHandler();
EducationBureauHandler educationBureauHandler = new EducationBureauHandler();
collegeManageHandler.setHandler(universityManageHandler);
universityManageHandler.setHandler(principalHandler);
principalHandler.setHandler(schoolstandingCommitteeHandler);
schoolstandingCommitteeHandler.setHandler(educationBureauHandler);
//开始审批
collegeManageHandler.processRequest(request);
}
}
总结
- 责任链模式将请求和处理分开,实现解耦,提高系统的灵活性
- 责任链模式简化了客户端,使得客户端不需要知道链的结构
- 使用责任链模式后代码会变得很多,会使程序的性能受到影响
- 采用了类似递归的操作,会使调试变得困难
- 最好使用在多级请求,各级权限不同的审批流程的应用场景中
希望对看到这里的诸位有所帮助,如果喜欢这篇个人理解不妨点一个赞,谢谢~。