概念
职责链模式:避免将一个请求的发送者与接收者耦合在一起,让多个对象都有机会处理请求。将接收请求的对象连接成一条链,并且沿着这条链传递请求,直到有一个对象能够处理它为止。
比如大学期间,我们进行奖学金申请,100到1000是导员审批,1000到2000是系主任审批,2000到5000是院长审批。
每一个人审批的内容都是不同的,如果有一个审批者认为不符合自己的审批条件,则将审批流转到下一个人。而我们也只需要和导员提交申请,不需要关注后面的审批人。
结构
Handler(抽象处理者):它定义了一个处理请求的接口,由于不同的具体处理者处理请求的方式不同,每一个处理者的下家还是一个处理者,故在其定义了一个抽象处理者类型的对象作为下家的引用。
ConcreteHandler(具体处理者):在具体处理者中实现了抽象处理者中的方法,在处理请求之前需要进行判断,看是否具有相应的处理权限,有的话则处理,没有的话则将请求转发给后继者。
实例
某企业的采购系统包含一个审批的子系统,可以根据采购金额不同,由不同层次的主管人员来审批。主任审批5万元以下的,副董事长审批5w到10w的,董事长审批10w到50w的,50w以上的采购需要开董事会来讨论决定。
采购单类,充当请求类。
@Data
public class PurchaseRequest {
// 采购金额
private double amount;
// 采购单编号
private int number;
// 采购目的
private String request;
public PurchaseRequest(double amount, int number, String request) {
this.amount = amount;
this.number = number;
this.request = request;
}
}
审批者的抽象类
public abstract class Approver {
//定义后继对象
protected Approver successor;
protected String name;
public Approver(String name) {
this.name = name;
}
public void setSuccessor(Approver approver){
this.successor = approver;
}
public abstract void processRequest(PurchaseRequest request);
}
主任类,充当具体处理者
public class Director extends Approver {
public Director(String name) {
super(name);
}
@Override
public void processRequest(PurchaseRequest request) {
if (request.getAmount() < 50000) {
System.out.println("主任:" + this.name + "审批采购单:" + request.getNumber() + ",金额:" + request.getAmount() + "元,采购目的:" + request.getRequest() + ".");
} else {
this.successor.processRequest(request);
}
}
}
副董事长类
public class VicePresident extends Approver {
public VicePresident(String name) {
super(name);
}
@Override
public void processRequest(PurchaseRequest request) {
if (request.getAmount() < 100000) {
System.out.println("副董事长:" + this.name + "审批采购单:" + request.getNumber() + ",金额:" + request.getAmount() + "元,采购目的:" + request.getRequest() + ".");
} else {
this.successor.processRequest(request);
}
}
}
董事长类
public class President extends Approver {
public President(String name) {
super(name);
}
@Override
public void processRequest(PurchaseRequest request) {
if (request.getAmount() < 500000) {
System.out.println("董事长:" + this.name + "审批采购单:" + request.getNumber() + ",金额:" + request.getAmount() + "元,采购目的:" + request.getRequest() + ".");
} else {
this.successor.processRequest(request);
}
}
}
董事会
public class Congress extends Approver{
public Congress(String name) {
super(name);
}
@Override
public void processRequest(PurchaseRequest request) {
System.out.println("召开董事会审批采购单:" + request.getNumber() + ",金额:" + request.getAmount() + "元,采购目的:" + request.getRequest() + ".");
}
}
客户端使用
public class Client {
public static void main(String[] args) {
Approver director = new Director("张三");
Approver vicePresident = new VicePresident("李四");
Approver president = new President("王五");
Approver congress = new Congress("董事会");
director.setSuccessor(vicePresident);
vicePresident.setSuccessor(president);
president.setSuccessor(congress);
PurchaseRequest purchaseRequest1 = new PurchaseRequest(45000, 10001, "购买员工座椅");
PurchaseRequest purchaseRequest2 = new PurchaseRequest(60000, 10002, "购买员工电脑");
director.processRequest(purchaseRequest1);
director.processRequest(purchaseRequest2);
}
}
执行结果:
总结
职责链模式通过建立一条链来组织请求的处理者,请求将沿着链进行传递。请求发送者无需知道请求被谁处理,实现了请求发送者和处理者之间的解耦。
使用场景:
1、当多个对象可以处理同一个请求,但每个对象处理的方式、时机不同,可以考虑使用职责链。
2、在不明确指定接受者的情况下向多个对象中的一个提交一个请求。
3、可动态指定一组对象处理请求,客户端动态的创建职责链来处理请求,还可以改变链中处理者之间的先后顺序。