职责链模式:又叫责任链模式,为请求创建了一个接收者对象的链,使得多个对象都有机会处理请求,从而对请求的发送者和接收者进行解耦。职责链模式通常每个接收者都包含另一个接收者的引用。如果一个对象可以包含对另一个接收者的引用,如果一个对象不能处理请求,那么它会把相同的请求传给下一个接收者。
类图
职责链的模式和职责:
1)Handler:抽象的处理者,定义了一个处理请求的接口,同时包含了另外的Handler
2)ConcreteHandlerA、B;具体的处理者,处理他自己负责的请求,同时可以访问它的后继者(即下一个处理者),如果可以处理当前请求,则自己处理请求,否则就访问后继者,从而形成职责链。
3)Request:处理请求。
案例
有一个学校采购OA系统,不同价格的物品要不同级别的人审批,比如小于5000元的物品要系主任审批,小于5000大于10000的物品要学院主任审批,大于10000元的物品要校长审批。
传统的解决方案是接收到采购请求后,用if、else语句根据判断具体的执行人来执行,这样做的缺点是请求和执行人存在强耦合关系,另外违反了开闭原则,如果金额要变动或者审核人要变动就得修改处理类的代码,不利于维护。
下面使用职责链模式解决传统模式的弊端:
处理抽象类
public abstract class Approver {
Approver approver;
String name;
public Approver(String name) {
this.name=name;
}
//用于设置职责链间的关系
public void setApprover(Approver approver) {
this.approver = approver;
}
public abstract void processRequest(PurchaseRequest purchaseRequest);
}
请求类
public class PurchaseRequest {
private int type;
private float price;
private int id;
public PurchaseRequest(int type, float price, int id) {
this.type = type;
this.price = price;
this.id = id;
}
public int getType() {
return type;
}
public float getPrice() {
return price;
}
public int getId() {
return id;
}
}
具体请求类
public class DepartmentApprover extends Approver {
public DepartmentApprover(String name) {
super(name);
}
@Override
public void processRequest(PurchaseRequest purchaseRequest) {
if(purchaseRequest.getPrice()<=5000){
System.out.println("请求编号id="+purchaseRequest.getId()+"被"+this.name+"处理");
}else{
approver.processRequest(purchaseRequest);
}
}
}
public class CollegeApprover extends Approver {
public CollegeApprover(String name) {
super(name);
}
@Override
public void processRequest(PurchaseRequest purchaseRequest) {
if(purchaseRequest.getPrice()>5000&&purchaseRequest.getPrice()<=10000){
System.out.println("请求编号id="+purchaseRequest.getId()+"被"+this.name+"处理");
}else{
approver.processRequest(purchaseRequest);
}
}
}
public class MasterApprover extends Approver {
public MasterApprover(String name) {
super(name);
}
@Override
public void processRequest(PurchaseRequest purchaseRequest) {
if(purchaseRequest.getPrice()>5000&&purchaseRequest.getPrice()<=10000){
System.out.println("请求编号id="+purchaseRequest.getId()+"被"+this.name+"处理");
}else{
approver.processRequest(purchaseRequest);
}
}
}
客户端调用
public class Client {
public static void main(String[] args) {
PurchaseRequest purchaseRequest=new PurchaseRequest(1,6000,1);
DepartmentApprover departmentApprover=new DepartmentApprover("张主任");
CollegeApprover collegeApprover=new CollegeApprover("王主任");
MasterApprover masterApprover=new MasterApprover("李校长");
departmentApprover.setApprover(collegeApprover);
collegeApprover.setApprover(masterApprover);
departmentApprover.processRequest(purchaseRequest);
}
}
结果
职责链模式的优缺点:
优点:
(1) 职责链模式使得一个对象无须知道是其他哪一个对象处理其请求,对象仅需知道该请求会被处理即可,接收者和发送者都没有对方的明确信息,且链中的对象不需要知道链的结构,由客户端负责链的创建,降低了系统的耦合度。
(2) 请求处理对象仅需维持一个指向其后继者的引用,而不需要维持它对所有的候选处理者的引用,可简化对象的相互连接。
(3) 在系统中增加一个新的具体请求处理者时无须修改原有系统的代码,只需要在客户端重新建链即可。
缺点:
(1) 由于一个请求没有明确的接收者,那么就不能保证它一定会被处理,该请求可能一直到链的末端都得不到处理;一个请求也可能因职责链没有被正确配置而得不到处理。
(2) 对于比较长的职责链,请求的处理可能涉及到多个处理对象,系统性能将受到一定影响,而且在进行代码调试时不太方便。
适用场景:
有多个对象可以处理同一个请求,具体哪个对象处理该请求待运行时刻再确定,客户端只需将请求提交到链上,而无须关心请求的处理对象是谁以及它是如何处理的。