需求
- 费用报销审批
- 请求审批
代码实现
员工
/**
* @author BNTang
* @program design-pattern-pro
* @date Created in 2021/10/12 012 9:58
* @description
**/
public class Employee {
private int money;
public void getApply() {
System.out.println("需要出差的费用是:" + getMoney());
}
}
组长
/**
* @author BNTang
* @program design-pattern-pro
* @date Created in 2021/10/12 012 10:03
* @description
**/
public class GroupLeader {
public void handler(Employee employee) {
employee.getApply();
System.out.println("我是组长:你需要申请的" + employee.getMoney() + "批准了");
}
}
经理
/**
* @author BNTang
* @program design-pattern-pro
* @date Created in 2021/10/12 012 10:05
* @description
**/
public class Manager {
public void handler(Employee employee) {
employee.getApply();
System.out.println("我是经理:你需要申请的" + employee.getMoney() + "批准了");
}
}
总经理
/**
* @author BNTang
* @program design-pattern-pro
* @date Created in 2021/10/12 012 10:06
* @description
**/
public class GeneralManager {
public void handler(Employee employee) {
employee.getApply();
System.out.println("我是总经理:你需要申请的" + employee.getMoney() + "批准了");
}
}
客户端使用
/**
* 客户端
*
* @author BNTang
*/
public class Client {
public static void main(String[] args) {
GroupLeader groupLeader = new GroupLeader();
Manager manager = new Manager();
GeneralManager generalManager = new GeneralManager();
Employee employee = new Employee();
employee.setMoney(1000);
if (employee.getMoney() <= 500) {
groupLeader.handler(employee);
} else if (employee.getMoney() <= 1000) {
manager.handler(employee);
} else if (employee.getMoney() <= 1500) {
generalManager.handler(employee);
}
// 1.具体是谁申请出差费用我们不管,我们只管申请出差需要做那些事!
// 2.具体是谁审批我们不需要纠结,我们只管审批需要做哪些事
}
}
存在问题
- 具体是谁申请出差费用我们不管,我们只管申请出差需要做哪些事
- 具体是谁审批我们不需要纠结,我们只管审批需要做哪些事
责任链模式定义
可以在系统中建立一个链,这样消息可以在首先接收到它的级别处被处理,或者可以定位到可以处理它的对象。为了避免请求发送者与多个请求处理者耦合在一起,将所有请求的处理者通过前一对象记住其下一个对象的引用而连成一条链。当有请求发生时,可将请求沿着这条链传递,直到有对象处理它为止
主要角色
抽象处理者(Handler)角色
定义一个处理请求的接口,包含抽象处理方法和一个后继连接。
具体处理者(Concrete Handler)角色
实现抽象处理者的处理方法,判断能否处理本次请求,继者,如果可以处理请求则处理,否则将该请求转给它的后。
客户类(Client)角色
创建处理链,并向链头的具体处理者对象提交请求,它不关心处理细节和请求的传递过程。
责任链模式代码实现
将申请人操作抽象化
/**
* @author BNTang
* @program design-pattern-pro
* @date Created in 2021/10/12 012 10:22
* @description 将申请人的操作抽象化,不需要关心是谁来申请出差费用,只关心出差申请要做的事
**/
public abstract class ApplyPersonInfo {
int money;
/**
* 设置钱
*
* @param money 钱
*/
public abstract void setMoney(int money);
/**
* 得到钱
*
* @return int
*/
public abstract int getMoney();
public void getApply() {
System.out.println("需要出差的费用是:" + getMoney());
}
}
抽象处理类
/**
* @author BNTang
* @program design-pattern-pro
* @date Created in 2021/10/12 012 10:32
* @description
**/
public abstract class LeaderHandler {
/**
* 当前领导审核的金额
*/
int auditMoney;
/**
* 上级领导
*/
LeaderHandler superiorLeader;
/**
* 当前领导收到申请后处理的事情
*
* @param applyPersonInfo 申请人信息
*/
public abstract void handler(ApplyPersonInfo applyPersonInfo);
/**
* 设置当前领导的上级领导
*
* @param superiorLeader 上级领导
*/
public abstract void setSuperiorLeader(LeaderHandler superiorLeader);
public void dealInfo(ApplyPersonInfo applyPersonInfo) {
if (applyPersonInfo.money <= auditMoney) {
handler(applyPersonInfo);
} else {
superiorLeader.dealInfo(applyPersonInfo);
}
}
}
具体处理者
组长
/**
* @author BNTang
* @program design-pattern-pro
* @date Created in 2021/10/12 012 10:38
* @description
**/
public class GroupLeader extends LeaderHandler {
GroupLeader() {
super.auditMoney = 500;
}
public void handler(ApplyPersonInfo applyPersonInfo) {
applyPersonInfo.getApply();
System.out.println("我是组长,你需要申请的:" + applyPersonInfo.getMoney() + "我批准了");
}
public void setSuperiorLeader(LeaderHandler superiorLeader) {
super.superiorLeader = superiorLeader;
}
}
经理
/**
* @author BNTang
* @program design-pattern-pro
* @date Created in 2021/10/12 012 10:38
* @description
**/
public class Manager extends LeaderHandler {
Manager() {
super.auditMoney = 1000;
}
public void handler(ApplyPersonInfo applyPersonInfo) {
applyPersonInfo.getApply();
System.out.println("我是经理,你需要申请的:" + applyPersonInfo.getMoney() + "我批准了");
}
public void setSuperiorLeader(LeaderHandler superiorLeader) {
super.superiorLeader = superiorLeader;
}
}
总经理
/**
* @author BNTang
* @program design-pattern-pro
* @date Created in 2021/10/12 012 10:38
* @description
**/
public class GeneralManager extends LeaderHandler {
GeneralManager() {
super.auditMoney = 1500;
}
public void handler(ApplyPersonInfo applyPersonInfo) {
applyPersonInfo.getApply();
System.out.println("我是总经理,你需要申请的:" + applyPersonInfo.getMoney() + "我批准了");
}
public void setSuperiorLeader(LeaderHandler superiorLeader) {
super.superiorLeader = superiorLeader;
}
}
修改 Employee.java:
/**
* @author BNTang
* @program design-pattern-pro
* @date Created in 2021/10/12 012 9:58
* @description
**/
public class Employee extends ApplyPersonInfo {
public void setMoney(int money) {
super.money = money;
}
public int getMoney() {
return super.money;
}
}
客户端调用
/**
* @author BNTang
* @program design-pattern-pro
* @date Created in 2021/10/12 012 10:48
* @description
**/
public class Client {
public static void main(String[] args) {
GroupLeader groupLeader = new GroupLeader();
Manager manager = new Manager();
GeneralManager generalManager = new GeneralManager();
groupLeader.setSuperiorLeader(manager);
manager.setSuperiorLeader(generalManager);
Employee employee = new Employee();
employee.setMoney(1500);
groupLeader.dealInfo(employee);
}
}
UML 图
优点
????????降低了耦合度
该模式降低了请求发送者和接收者的耦合度
????增强了系统的可扩展性
可以根据需要增加新的请求处理类,满足开闭原则
????增加新对象指定责任的灵活性
当工作流程发生变化,可以动态地改变链内的成员或者修改它们的次序,也可动态地新增或者删除责任
由于在一个类中产生的事件可以被发送到组成中的其他类处理器上,类的集合可以作为一个整体
????责任分担
每个类只需要处理自己该处理的工作,不能处理的传递给下一个对象完成,明确各类的责任范围,符合类的单一职责原则
缺点
不能保证每个请求一定被处理。由于一个请求没有明确的接收者,所以不能保证它一定会被处理,该请求可能一直传到链的末端都得不到处理,对比较长的职责链,请求的处理可能涉及多个处理对象,系统性能将受到一定影响。职责链建立的合理性要靠客户端来保证,增加了客户端的复杂性,可能会由于职责链的错误设置而导致系统出错,如可能会造成循环调用。
使用场景
多个对象可以处理一个请求,而其处理器却是未知的,想要在不指定确切的请求接收对象的情况下,向几个对象中的一个发送请求。可以动态地指定能够处理请求的对象集。
源码
- JavaWeb Filter