一、概念
职责链是一种行为型模式,通过创建一条链来组织请求处理者和处理行为,请求发送者无须知道请求在何时、何处以及如何被处理,实现了请求发送者与处理者的解耦。
由客户端负责链的创建,当系统中新增处理者或修改处理链路时,无须修改系统代码,只需要在客户端重新建链即可,具有良好的灵活性,符合开闭原则。
二、应用场景
典型的应用场景包括:
1、Web应用中的过滤器(Filter)
2、工作流引擎中的审批流程
三、典型代码
Classgram of pattern of chain of responsibility
Handler.java
package patterns.chain_of_responsibility.definition;
public abstract class Handler {
protected Handler successor;
public void setSuccessor(Handler successor) {
this.successor = successor;
}
public abstract void handleRequest(Object request);
}
ConcreteHandler.java
package patterns.chain_of_responsibility.definition;
public class ConcreteHandler extends Handler {
@Override
public void handleRequest(Object request) {
if("one".equals(request)) { //满足条件
//处理代码
} else {
this.successor.handleRequest(request); //转发请求
}
}
}
四、示例:
审批项目场景:
50万元(不含)以内的项目:部门经理有审批权;
50万元(含)~200万元(不含):公司总监有审批权;
200万元(含)~500万元(不含):公司总裁有审批权;
500万元(含)以上:召开董事会决议。
1、请求类:ProjectRequest.java
package patterns.chain_of_responsibility.example;
//请求类:项目申请
public class ProjectRequest {
private double amount; //项目金额
private String id; //项目编号
private String desc; //项目说明
public ProjectRequest(double amount, String id, String desc) {
super();
this.amount = amount;
this.id = id;
this.desc = desc;
}
public double getAmount() {
return amount;
}
public void setAmount(double amount) {
this.amount = amount;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
}
2、抽象审批者类:Approver.java
package patterns.chain_of_responsibility.example;
public abstract class Approver {
protected Approver successor; //后继审批者
protected String name; //审批者姓名
public Approver(String name) {
super();
this.name = name;
}
//设置后继者
public void setSuccessor(Approver successor) {
this.successor = successor;
}
//抽象请求处理方法
public abstract void processRequest(ProjectRequest request);
}
3、具体审批者类:经理(Manager.java)、总监(Director.java)、总裁(President.java)、董事会(Congress.java)
package patterns.chain_of_responsibility.example;
//经理
public class Manager extends Approver {
public Manager(String name) {
super(name);
}
@Override
public void processRequest(ProjectRequest request) {
if(request.getAmount() < 500000) {
System.out.println(this.name + "(经理)审批项目申请单:" + request.getId() + ",项目金额:"
+ request.getAmount() + "元,项目说明:" + request.getDesc() + "。");
} else {
this.successor.processRequest(request);
}
}
}
package patterns.chain_of_responsibility.example;
//总监
public class Director extends Approver {
public Director(String name) {
super(name);
}
@Override
public void processRequest(ProjectRequest request) {
if(request.getAmount() < 2000000) {
System.out.println(this.name + "(总监)审批项目申请单:" + request.getId() + ",项目金额:"
+ request.getAmount() + "元,项目说明:" + request.getDesc() + "。");
} else {
this.successor.processRequest(request);
}
}
}
package patterns.chain_of_responsibility.example;
//总裁
public class President extends Approver {
public President(String name) {
super(name);
}
@Override
public void processRequest(ProjectRequest request) {
if(request.getAmount() < 5000000) {
System.out.println(this.name + "(总裁)审批项目申请单:" + request.getId() + ",项目金额:"
+ request.getAmount() + "元,采购说明:" + request.getDesc() + "。");
} else {
this.successor.processRequest(request);
}
}
}
package patterns.chain_of_responsibility.example;
public class Congress extends Approver {
public Congress(String name) {
super(name);
}
@Override
public void processRequest(ProjectRequest request) {
System.out.println("董事会审议项目申请:" + request.getId() + ",项目金额:"
+ request.getAmount() + "元,项目说明:" + request.getDesc() + "。");
}
}
4、客户端:Client.java
package patterns.chain_of_responsibility.example;
public class Client {
public static void main(String[] args) {
Approver manager = new Manager("张飞");
Approver director = new Director("关羽");
Approver president = new President("刘备");
Approver congress = new Congress("董事会");
//创建职责链
manager.setSuccessor(director);
director.setSuccessor(president);
president.setSuccessor(congress);
//创建项目申请单
ProjectRequest pr1 = new ProjectRequest(499000, "P0001", "买酒");
manager.processRequest(pr1);
ProjectRequest pr2 = new ProjectRequest(1898000, "P0002", "建粮仓");
manager.processRequest(pr2);
ProjectRequest pr3 = new ProjectRequest(4660000, "P0003", "建军马场");
manager.processRequest(pr3);
ProjectRequest pr4 = new ProjectRequest(8825000, "P0004", "研发新兵器");
manager.processRequest(pr4);
}
}
【运行结果】
张飞(经理)审批项目申请单:P0001,项目金额:499000.0元,项目说明:买酒。
关羽(总监)审批项目申请单:P0002,项目金额:1898000.0元,项目说明:建粮仓。
刘备(总裁)审批项目申请单:P0003,项目金额:4660000.0元,采购说明:建军马场。
董事会审议项目申请:P0004,项目金额:8825000.0元,项目说明:研发新兵器。