在生活中经常见到这样的流程:员工请假,先由项目组长审批,再由部门经理审批,最后由人事归档。
每个审批环节都对应着不同的角色,每个角色有不同的职责,处理完职责对应的工作后,再将任务传递给下一个。
其实,在我们程序开发中,这种职责链也常常出现。笔者在这里以HTTP请求举个例子。
我们知道HTTP是基于TCP的应用层协议,当用户从浏览器发起一个请求时,服务器接收到的实际是二进制数据,服务器会将二进制数据按照HTTP协议规范进行解码,从而得到HTTP原始对象,而我们往往需要把HTTP原始对象中再转成我们的Java对象或者JsonObject。这样想想,这个解码动作是不是层层传递的。有将二进制数据转成HTTP对象的解码器,然后又传递给将HTTP对象转成我们业务需要的Java对象的解码器,最后再将解码后的对象传递给实际业务处理器(Handler/Controller)。
上面举的这个例子在Netty中就得到了很好的体现。对Netty有接触过的同学应该知道pipeline。pipeline就是职责链模式的实现。
说了这么多,不如来点实际的,笔者用Java实现一个员工请假审批的职责链。需求如下:
当请假天数 days <= 5 先由项目组长审批后,再传递给部门经理审批,最后再由部门经理传递给人事归档。当请假天数 days > 5 的时候项目组长和部门经理都会拒绝审批,不再传递。
1、编写假条类 Leave.java
package com.javafm.chain;
public class Leave {
private String name;
private int days;
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;
}
}
2、编写审批的抽象类 Approval.java
package com.javafm.chain;
public abstract class Approval {
// 审批者名称
private String name;
// 下一个审批者
protected Approval next;
public Approval(String name) {
this.name = name;
}
public void addLast(Approval approval) {
this.next = approval;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void process(Leave leave) {
System.out.println(this.getName() + "处理了审批:" + leave.getName() + " 请假 " + leave.getDays() + " 天");
}
}
3、编写项目组长审批类 Leader.java
package com.javafm.chain;
public class Leader extends Approval {
public Leader() {
super("项目组长");
}
@Override
public void process(Leave leave) {
super.process(leave);
if (leave.getDays() > 5) {
System.out.println(this.getName() + "拒绝了该申请");
} else {
this.next.process(leave);
}
}
}
4、编写部门经理审批类 Manager.java
package com.javafm.chain;
public class Manager extends Approval {
public Manager() {
super("部门经理");
}
@Override
public void process(Leave leave) {
super.process(leave);
if (leave.getDays() > 5) {
System.out.println(this.getName() + "拒绝了该申请");
} else {
this.next.process(leave);
}
}
}
5、编写人事归档类
package com.javafm.chain;
public class HrMM extends Approval {
public HrMM() {
super("HR MM");
}
@Override
public void process(Leave leave) {
System.out.println(this.getName() + "归档完毕:" + leave.getName() + " 请假 " + leave.getDays() + " 天");
}
}
从上面的代码可以看到项目组长审批类、项目经理审批类、人事归档类都继承了审批的抽象类。并且重写了process方法。
5、编写测试代码 Main.java
package com.javafm.chain;
public class Main {
public static void main(String[] args) {
Leave leave = new Leave();
leave.setName("皮花猫");
leave.setDays(3);
Approval leader = new Leader();
Approval manager = new Manager();
Approval hrmm = new HrMM();
leader.addLast(manager);
manager.addLast(hrmm);
leader.process(leave);
}
}
6、运行测试代码后,在控制台会输出以下信息,从中可以看到审批流程是按职责层层传递的。