什么是责任链模式
责任链模式(Chain of Responsibility Pattern)在设计模式里属于行为型模式。在这种模式中,通常每个接收者都包含对另一个接收者的引用。从而形成一个调用链。请求在这个链上传递,直到链上的某一个对象决定处理此请求。发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,这使得系统可以在不影响客户端的情况下动态地重新组织和分配责任。
为了便于理解,下面我将使用责任链模式来实现一个请假流程:
既然是请假流程,肯定是有相关的请求信息,所以首先定义一个请求类,有请求类型、天数、备注这三个属性
public class Request {
private String type; // 请求类型
private int days; // 天数
private String remarks; // 备注
public Request() {
}
public Request(String type, int days, String remarks) {
this.type = type;
this.days = days;
this.remarks = remarks;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public int getDays() {
return days;
}
public void setDays(int days) {
this.days = days;
}
public String getRemarks() {
return remarks;
}
public void setRemarks(String remarks) {
this.remarks = remarks;
}
}
请求类型枚举类
public enum RequestTypeEnum {
LEAVE("leave","请假");
private String code;
private String desc;
private RequestTypeEnum(String code, String desc) {
this.code = code;
this.desc = desc;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
/**
* 通过code取得类型
*
* @param code
* @return
*/
public static RequestTypeEnum getProductFeeTypeEnum(String code) {
for (RequestTypeEnum type : RequestTypeEnum.values()) {
if (type.getCode().equals(code)) {
return type;
}
}
return null;
}
}
然后定义一个管理者类,紧接着是相关子类,如下
public abstract class Manage {
protected String level;
protected Manage superior;
public Manage(String level){
this.level = level;
}
/**
* 设置管理者上级
*
* @param superior
*/
public void setSuperior(Manage superior) {
this.superior = superior;
}
/**
* 申请请求
*
* @param request
*/
public abstract void request(Request request);
}
‘经理类’继承管理者类,重写request
方法,可以处理2天以内的请假申请
public class Manager extends Manage {
public Manager(String level){
super(level);
}
@Override
public void request(Request request) {
// 经理能处理2天以内的请假申请
if (RequestTypeEnum.LEAVE.getCode().equals(request.getType()) && request.getDays() <= 2) {
System.out.println("经理开始处理 >>>>>>>");
System.out.println("因" + request.getRemarks() + ",需请假" + request.getDays() + "天,已批准。");
} else {
// 处理不了的传递给上级
if (superior != null) {
System.out.println("经理处理不了,需上级处理 >>>>>>>");
superior.request(request);
}
}
}
}
‘总监类’同样继承管理者类,重写request
方法,可以处理5天以内的请假申请
public class InspectorGeneral extends Manage {
public InspectorGeneral(String level){
super(level);
}
@Override
public void request(Request request) {
// 总监能处理5天以内的请假申请
if (RequestTypeEnum.LEAVE.getCode().equals(request.getType()) && request.getDays() <= 5) {
System.out.println("总监开始处理 >>>>>>>");
System.out.println("因" + request.getRemarks() + ",需请假" + request.getDays() + "天,已批准。");
} else {
// 处理不了的传递给上级
if (superior != null) {
superior.request(request);
}
}
}
}
‘总经理类’同样继承管理者类,重写request
方法,可以处理任意天数的请假申请
public class GeneralManager extends Manage {
public GeneralManager(String level){
super(level);
}
@Override
public void request(Request request) {
// 总经理可处理任意天数的请假申请
if (RequestTypeEnum.LEAVE.getCode().equals(request.getType())) {
System.out.println("总经理开始处理 >>>>>>>");
System.out.println("因" + request.getRemarks() + ",需请假" + request.getDays() + "天,已批准。");
}
}
}
再定义一个管理类工厂,初始化请假流程实例
public class ManageFactory {
public static Manage getManage(){
Manager manager = new Manager("经理");
InspectorGeneral inspectorGeneral = new InspectorGeneral("总监");
GeneralManager generalManager = new GeneralManager("总经理");
// 设置经理的上级为总监
manager.setSuperior(inspectorGeneral);
// 设置总监的上级为总经理
inspectorGeneral.setSuperior(generalManager);
return manager;
}
}
下面来测试
public class Test {
public static void main(String[] args) {
Manage manage = ManageFactory.getManage();
System.out.println("流程1开始 >>>>>>>>");
Request requestOne = new Request(RequestTypeEnum.LEAVE.getCode(),1,"生病请假");
manage.request(requestOne);
System.out.println("流程2开始 >>>>>>>>");
Request requestTwo = new Request(RequestTypeEnum.LEAVE.getCode(),5,"休息");
manage.request(requestTwo);
System.out.println("流程3开始 >>>>>>>>");
Request requestThree = new Request(RequestTypeEnum.LEAVE.getCode(),10,"休假");
manage.request(requestThree);
}
}
输出结果如下
流程1开始 >>>>>>>>
经理开始处理 >>>>>>>
因生病请假,需请假1天,已批准。
流程2开始 >>>>>>>>
经理处理不了,需上级处理 >>>>>>>
总监开始处理 >>>>>>>
因休息,需请假5天,已批准。
流程3开始 >>>>>>>>
经理处理不了,需上级处理 >>>>>>>
总监处理不了,需上级处理 >>>>>>>
总经理开始处理 >>>>>>>
因休假,需请假10天,已批准。