责任链模式(Chain of Responsibility Pattern)为请求创建了一个接收者对象的链。这种模式给予请求的类型,对请求的发送者和接收者进行解耦。这种类型的设计模式属于行为型模式。也就是将能够处理同一个请求的对象连成一条链,所提交的请求在链上有可传递性,即当前节点处理完可交由下个节点处理。
举个例子,一般公司里请假都需要提交请假申请,然后根据请假天数来决定相应的审批流程,这个审批流程就可以看成是一个链条,请假单需要经过这个完整链才算处理完。比如某公司的请假制度是这样的:1、请假天数为三天之内则由产品经理审批即可;2、三天到五天的还得经过部门经理审批;3、五天以上的还得通过总经理批准才行。
下面就用代码来实现一下这个流程。
先写一个假条信息类RequestLeave,有请假人、请假天数、请假原因几个属性:
package com.minant.responsibility;
/**
* @ClassName RequestLeave
* @Description TODO 请假信息单
* @Author MinAnt
* @Date 2020/5/27
* @Version V1.0
*/
public class RequestLeave {
// 请假人
private String name;
// 请假天数
private int days;
// 请假原因
private String reson;
public RequestLeave() {
}
public RequestLeave(String name, int days, String reson) {
this.name = name;
this.days = days;
this.reson = reson;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getDays() {
return days;
}
public void setDays(int days) {
this.days = days;
}
public String getReson() {
return reson;
}
public void setReson(String reson) {
this.reson = reson;
}
}
然后是抽象处理类AbstractLeader:
package com.minant.responsibility;
/**
* @ClassName AbstractLeader
* @Description TODO 抽象处理人
* @Author MinAnt
* @Date 2020/5/27
* @Version V1.0
*/
public abstract class AbstractLeader {
// 领导人
private String name;
// 职务
private String level;
// 下一位处理者
private AbstractLeader nextLeader;
public AbstractLeader(AbstractLeader nextLeader) {
this.nextLeader = nextLeader;
}
public AbstractLeader(String name, String level, AbstractLeader nextLeader) {
this.name = name;
this.level = level;
this.nextLeader = nextLeader;
}
public abstract void handle(RequestLeave requestLeave);
public AbstractLeader getNextLeader() {
return nextLeader;
}
public void setNextLeader(AbstractLeader nextLeader) {
this.nextLeader = nextLeader;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getLevel() {
return level;
}
public void setLevel(String level) {
this.level = level;
}
}
这个类中有包含有下一个处理人,这就是形成链结构的关键。之后是具体处理类,每个具体类都要继承自这个类以包括它的属性信息,实现抽象方法handle,用于处理审批假条。
package com.minant.responsibility;
/**
* @ClassName ProductManager
* @Description TODO 产品经理
* @Author MinAnt
* @Date 2020/5/27
* @Version V1.0
*/
public class ProductManager extends AbstractLeader {
public ProductManager(AbstractLeader nextLeader) {
super(nextLeader);
}
public ProductManager(String name, String level, AbstractLeader nextLeader) {
super(name, level, nextLeader);
}
@Override
public void handle(RequestLeave requestLeave) {
// 请假三天之内由产品经理直接审批
if(requestLeave.getDays() < 3) {
System.out.println(requestLeave.getName()+":请假【"+requestLeave.getDays()+"】天,"+this.getLevel()+":" +this.getName()+ " 表示:直接批准!");
System.out.println("流程结束!");
} else {
// 否则由上级领导审批
System.out.println(requestLeave.getName()+":请假【"+requestLeave.getDays()+"】天,"+this.getLevel()+":" +this.getName()+ " 表示:批准!");
this.getNextLeader().handle(requestLeave);
}
}
}
package com.minant.responsibility;
/**
* @ClassName DivisionManager
* @Description TODO 部门经理
* @Author MinAnt
* @Date 2020/5/27
* @Version V1.0
*/
public class DivisionManager extends AbstractLeader {
public DivisionManager(AbstractLeader nextLeader) {
super(nextLeader);
}
public DivisionManager(String name, String level, AbstractLeader nextLeader) {
super(name, level, nextLeader);
}
@Override
public void handle(RequestLeave requestLeave) {
// 请假不大于5天的,由部门经理复批
if(requestLeave.getDays() <= 5) {
System.out.println(requestLeave.getName()+":请假【"+requestLeave.getDays()+"】天,"+this.getLevel()+":" +this.getName()+ " 表示:批准!");
System.out.println("流程结束!");
} else {
// 否则由上级领导审批
System.out.println(requestLeave.getName()+":请假【"+requestLeave.getDays()+"】天,"+this.getLevel()+":" +this.getName()+ " 表示:批准!");
this.getNextLeader().handle(requestLeave);
}
}
}
package com.minant.responsibility;
/**
* @ClassName CompanyManager
* @Description TODO 公司总经理
* @Author MinAnt
* @Date 2020/5/27
* @Version V1.0
*/
public class CompanyManager extends AbstractLeader {
public CompanyManager(AbstractLeader nextLeader) {
super(nextLeader);
}
public CompanyManager(String name, String level, AbstractLeader nextLeader) {
super(name, level, nextLeader);
}
@Override
public void handle(RequestLeave requestLeave) {
if(requestLeave.getDays() > 30) {
System.out.println(requestLeave.getName()+":请假【"+requestLeave.getDays()+"】天,"+this.getLevel()+":" +this.getName()+ " 表示:不用来了!");
System.out.println("流程结束!");
} else if(requestLeave.getDays() > 5) {
System.out.println(requestLeave.getName()+":请假【"+requestLeave.getDays()+"】天,"+this.getLevel()+":" +this.getName()+ " 表示:批准!");
System.out.println("流程结束!");
}
}
}
最后测试:
package com.minant.responsibility;
/**
* @ClassName TestResponsibility
* @Description TODO 测试责任链模式
* @Author MinAnt
* @Date 2020/5/27
* @Version V1.0
*/
public class TestResponsibility {
public static void main(String[] args) {
// 请假单
RequestLeave laowan = new RequestLeave("老王", 3, "身体不适");
RequestLeave xiaomin = new RequestLeave("小明", 40, "世界那么大,我想去看看!");
// 责任链
CompanyManager companyManager = new CompanyManager("马总", "总经理", null);
DivisionManager divisionManager = new DivisionManager("刘老根", "部门经理",companyManager);
ProductManager productManager = new ProductManager("钢铁侠", "产品经理", divisionManager);
productManager.handle(laowan);
productManager.handle(xiaomin);
}
}
测试结果:
责任链模式到此结束。