小明公司要做财务ERP系统
小明公司随着项目的增多,公司发展得越来越壮大,所以有一些财务上的审批,如果报账的金额在100以下,团队主管直接审批后就可以,如果在100以上5000以下,需要部门经理审批,如果在5000以上,需要公司经理审批。公司想通过线上的方式去将这个流程实现
不出意外,小明负责这个程序的编写,小明这次很谨慎,因为之前做的东西都有一些不足的地方,所以小明再思考了一番后,开始编码去实现了
public class Reimbursement {
private float value;
public Reimbursement(float value) {
this.value = value;
}
public void handler() {
if (value <= 100) handleByLeader();
else if (value > 100 && value <= 5000) handleByManager();
else if (value > 500) handleByGeneralManager();
}
private void handleByLeader() {
// 处理省略
}
private void handleByManager() {
// 处理省略
}
private void handleByGeneralManager() {
// 处理省略
}
}
小明写完后仔细的思考了一下,这个代码存在很多问题,比如不符合单一原则,这个类负责了三个不同的事情。同时,不符合开闭原则,如果新增加一个审批角色,需要修改代码来扩展。但是小明一时也想不到解决办法,于是找到了主管,主管说,这是一个典型的责任链模式,我们可以通过责任链模式来设计这个项目
定义
避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止
用责任链模式来现实
首先我们要实现处理类
public abstract class Handler {
protected Handler nextHandler;
public void setNextHandler(Handler nextHandler) {
this.nextHandler = nextHandler;
}
public abstract void handleRequest(int request);
}
团队主管处理类:
public class LeaderHandler extends Handler {
@Override
public void handleRequest(int request) {
if (request < 100) {
System.out.println("团队主管处理了");
} else {
this.nextHandler.handleRequest(request);
}
}
}
经理处理类:
public class ManagerHandler extends Handler {
@Override
public void handleRequest(int request) {
if (request <= 5000) {
System.out.println("部门经理处理了");
} else {
this.nextHandler.handleRequest(request);
}
}
}
总经理处理类:
public class GeneralManagerHandler extends Handler {
@Override
public void handleRequest(int request) {
System.out.println("总经理处理了");
}
}
然后我们来开始报账
public class Client {
public static void main(String[] args) {
LeaderHandler leaderHandler = new LeaderHandler();
ManagerHandler managerHandler = new ManagerHandler();
GeneralManagerHandler generalManagerHandler = new GeneralManagerHandler();
leaderHandler.setNextHandler(managerHandler);
managerHandler.setNextHandler(generalManagerHandler);
leaderHandler.handleRequest(2000);
leaderHandler.handleRequest(50);
leaderHandler.handleRequest(6000);
}
}
结果:
部门经理处理了
团队主管处理了
总经理处理了
这样实现后,刚才小明想到的那两个问题也解决了,如果我们现在增加了一个环节,不需要修改请求者的代码,只需要在责任链中加入新的角色即可
纯与不纯的责任链模式
纯的责任链模式
一个纯的职责链模式要求一个具体处理者对象只能在两个行为中选择一个:要么承担全部责任,要么将责任推给下家,不允许出现某一个具体处理者对象在承担了一部分或全部责任后又将责任向下传递的情况。而且在纯的职责链模式中,要求一个请求必须被某一个处理者对象所接收,不能出现某个请求未被任何一个处理者对象处理的情况。在前面的采购单审批实例中应用的是纯的职责链模式
不纯的责任链模式
在一个不纯的职责链模式中允许某个请求被一个具体处理者部分处理后再向下传递,或者一个具体处理者处理完某请求后其后继处理者可以继续处理该请求,而且一个请求可以最终不被任何处理者对象所接收。Android的控件点击事件就是不纯的责任链模式,当点击控件时,Android系统将把事件发送到控件的顶层,然后从控件的顶层开始先下分发,某一层可以将该事件消费掉,也可以继续将该事件向下分发,不过每一层都会对事件进行一些处理