1.1例子
公司请假系统,业务逻辑如下:
不超过3天的,组长审批
超过3天且小于7天的,总监审批
超过7天且小于15天的,部长审批
超过15天,前端直接拒绝,不会进入审批流程(违反了公司的请假规定)
底层小职员请假,直接去OA系统填写请假申请,生成请假工单
系统会根据请假天数,将请假工单派发给对应的审批人
1.2 考虑使用责任链模式
以请假审批系统为例,组长 → \rightarrow→ 总监 → \rightarrow→ 部长形成了一条链
职员提交请假申请后,请求会沿着这条链传递,直到有对象可以处理它。
一个5天的请假申请,先到达组长处;
组长无权限审批,传递请求到自己的上级(总监);
总监有权限审批,于是同意了该请假申请
作为请求的发送者,职员无需关心最终由谁审批,只需要提交请求即可
这样的设计模式,就是责任链模式(Chain of Responsibility)
1.3 自己理解
一个请求可能需要由不同的handler独立处理,或者需要多个handler同时处理
如果按照常规的编程模式,可能需要繁杂的if-else去实现
将handler通过next引用形成一条责任链,请求发送者只需要发送请求到责任链
请求会在责任链中传递,直到被对应的handler处理(一个或多个)或者无法被处理
这样的话,请求发送者无需关心handler的处理逻辑和请求的传递过程,实现了请求的发送者和处理者的解耦。
1.4 实现一个请假系统
第一步:创建抽象处理者
public abstract class Handler {
private Handler next;
public void setNext(Handler next) {
this.next = next;
}
public Handler getNext() {
return next;
}
public abstract void handleRequest(String name, int days);
}
第二步:创建组长、总监、部长三个具体处理者,实现具体的处理逻辑
public class PMHandler extends Handler {
@Override
public void handleRequest(String name, int days) {
if (days <= 3) {
System.out.println(name + ",组长已经同意您的请假审批!");
} else {
if (getNext() != null) {
getNext().handleRequest(name, days);
} else {
System.out.println("请假天数太多,申请被驳回!");
}
}
}
}
public class DirectorHandler extends Handler {
@Override
public void handleRequest(String name, int days) {
if (days <= 7) {
System.out.println(name + ",中心总监已经同意您的请假审批");
} else {
if (getNext() != null) {
getNext().handleRequest(name, days);
} else {
System.out.println("请假天数太多,申请被驳回!");
}
}
}
}
public class MinisterHandler extends Handler {
@Override
public void handleRequest(String name, int days) {
if (days <= 15) {
System.out.println(name + ",部长已经同意您的请假审批");
} else {
if (getNext() != null) {
getNext().handleRequest(name, days);
} else {
System.out.println("请假天数太多,申请被驳回!");
}
}
}
}
第三步:创建Clinet类,在类中创建并使用责任链(向责任链传递请求)
public class OASystem {
public static void main(String[] args) {
// 创建具体处理者
Handler pm = new PMHandler();
Handler director = new DirectorHandler();
Handler minister = new MinisterHandler();
// 构建责任链
pm.setNext(director);
director.setNext(minister);
// 使用责任链
pm.handleRequest("张三", 5);
}
}
最终的执行结果如下: