基本介绍:
- 职责链模式,又叫责任链模式,为请求创建一个接收对象的链,这种模式对请求发送者和接收者进行解耦
- 职责链模式通常每个接受者都包含对另一个接收者的引用,如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依次类推
- 职责链模式属于行为模式
原理类图:
角色说明:
- Handler:抽象的处理者,定义了一个处理请求的接口,同时含有另外Handler
- ConcreteHandlerA,B:具体的处理者,处理他自己负责的请求,可以访问它的后继者即后一个处理者,如果可以处理当前请求,则处理,否则就将该请求交给后继者处理,从而形成一个职责链
- Request:含有很多属性,表示一个请求
实例:
完成学校OA系统的采购商品项目,需求采购员采购学校器材
如果金额小于等于5000,由教学主任审批
如果金额小于等于10000,由院长审批
如果金额小于等于30000,由副校长审批
如果金额大于30000,由校长审批
public abstract class Approver {
Approver approver;
String name;
public Approver(String name) {
this.name = name;
}
public void setApprover(Approver approver) {
this.approver = approver;
}
abstract void proccess(PurchaseRequest purchaseRequest);
}
public class DepartmentApprover extends Approver {
public DepartmentApprover(String name) {
super(name);
}
@Override
void proccess(PurchaseRequest purchaseRequest) {
if(purchaseRequest.getPrice() <=5000){
System.out.println("教导主任处理了。。");
}else {
approver.proccess(purchaseRequest);
}
}
}
public class CollegeApprover extends Approver {
public CollegeApprover(String name) {
super(name);
}
@Override
void proccess(PurchaseRequest purchaseRequest) {
if (5000 < purchaseRequest.getPrice() && purchaseRequest.getPrice() <= 10000) {
System.out.println("被院长处理了。。");
} else {
approver.proccess(purchaseRequest);
}
}
}
public class ViceSchoolMasterApprover extends Approver {
public ViceSchoolMasterApprover(String name) {
super(name);
}
@Override
void proccess(PurchaseRequest purchaseRequest) {
if (10000 < purchaseRequest.getPrice() && purchaseRequest.getPrice() <= 30000) {
System.out.println("被副校长处理了。。");
} else {
approver.proccess(purchaseRequest);
}
}
}
public class SchoolMasterApprover extends Approver {
public SchoolMasterApprover(String name) {
super(name);
}
@Override
void proccess(PurchaseRequest purchaseRequest) {
if (purchaseRequest.getPrice() > 30000) {
System.out.println("被校长处理了。。");
} else {
approver.proccess(purchaseRequest);
}
}
}
public class PurchaseRequest {
private int type = 0;
private int id = 0;
private float price = 0.0f;
public PurchaseRequest(int type, int id, float price) {
this.type = type;
this.id = id;
this.price = price;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public float getPrice() {
return price;
}
public void setPrice(float price) {
this.price = price;
}
}
public class Client {
public static void main(String[] args) {
PurchaseRequest purchaseRequest = new PurchaseRequest(1, 1,1010.0f);
DepartmentApprover departmentApprover = new DepartmentApprover("李主任");
CollegeApprover collegeApprover = new CollegeApprover("张院长");
ViceSchoolMasterApprover viceSchoolMasterApprover = new ViceSchoolMasterApprover("孙副校长");
SchoolMasterApprover schoolMasterApprover = new SchoolMasterApprover("赵校长");
departmentApprover.setApprover(collegeApprover);
collegeApprover.setApprover(viceSchoolMasterApprover);
viceSchoolMasterApprover.setApprover(schoolMasterApprover);
//让处理链形成一个换,不会出现空指针
schoolMasterApprover.setApprover(departmentApprover);
departmentApprover.proccess(purchaseRequest);
}
}
职责链在Springmvc中的使用:
当请求进来时,先进入DispatcherServlet,调用HandlerInterceptor.perHandler,然后调用postHandler方法
,再调用afterCompletion方法
- spring mvc请求的流程图中,执行了拦截器相关方法,interceptor.preHandler等等
- 在处理spring mvc请求时,使用到职责链模式还使用到了适配器模式
- handlerExecutionChain,主要负责的是请求拦截器的执行和请求处理,但是它本身不处理请求,只是将请求分配给链上注册的处理器执行,这是责任链实现方式,减少职责链本身与处理逻辑之间的耦合,规范了处理流程
- HandlerExecutionChain维护了HandlerInterceptor的集合,可以向其中注册相应的拦截器
职责链模式的注意事项和细节:
- 将请求和处理分开,实现解耦,提高了系统的灵活性
- 简化了对象,使对象不需要知道链的结构
- 性能会受到影响,特别是链比较长的时候,因此需要控制链的最大节点数量,一般通过handler中设置一个最大节点数量,在setNext()方法中判断是否已经超过了阈值,超过了则不允许该链建立,避免出现超长链无意识的破坏系统性能
- 调试不方便,采用了类似递归的方式,调试时逻辑可能比较复杂
- 最佳使用场景:有多个对象可以处理同一个请求时,比如:多级请求、审批流程、拦截器、java web中tomcat对Encoding的处理
总结:
- 设计模式是编程中有意或者无意使用到的,并且同一种设计模式也不是100%的一样,设计模式主要是提高程序的扩展性、可读性、可维护性、规范性
- 设计模式是可以结合使用,源码中可能部分使用到了A模式,也有可能部分使用到了B模式
- 设计模式主要是一种编程思想,既然是思想具体实现方式就不会完全相同(当然,程序的设计结构基本是一样的)
- 学习设计模式或源码分析时,应该抓住本质,就是使用这个设计模式到底带来了什么好处,是扩展性提高了,还是更加规范了,这样才能更好的领会设计模式的精妙之处