🌲1.描述
责任链模式就是完成一件任务,现在有一群做任务的主体,完成这件任务可能需要这些主体中的一个或者多个。
那我们就把这个任务交给这些主体,让他们依次传递处理这件任务。
这些主体在完成一件任务的时候,可以抽象出两个概念:顺序和数量。
🥇顺序:做任务的主体接收任务的时候有没有先后顺序
🥈数量:做这件任务是需要一个主体,还是多个主体。
😀把顺序和数量组合形成四种组合方式
🍇一个主体有先后顺序: 请假审批业务,现在有经理、部门经理、总经理三个角色,我们请假的时候只要有一个角色审批了就可以请假了;在请假任务的传递过程中先给经理,再给部门经理,最后给总经理。是有先后顺序的。
🍈一个主体无先后顺序: 邮递业务,现在有顺丰、中通、申通三家快递公司,只要有一家接收了快递,投递物件这个任务就完成了。在选择快递公司的时候没有明确的需求说先考虑哪个公司再考虑哪个公司,只要条件某家快递公司符合条件就可以收件。
🍉多个主体有先后顺序: 报销审批业务,现在有经理、部门经理、总经理三个角色,我们在报销的时候需要所有角色审批通过才能报销,而且审批的时候有先后顺序,先经理审批,审批通过交给部门经理,部门经理审批通过交给总经理。
🍊多个主体无先后顺序: 商品打折业务,商品在打折的时候有多种打折方式,新用户折扣、节假日折扣、周年庆折扣。这三种折扣没有先后顺序只要符合就对商品价格进行运算。
🌱2.示例
这里我们用报销审批这个业务来做一个示例代码
- 💐抽象类: 所有经理需要实现这个抽象类,并且要实现方法,这个抽象类的作用有两个:约束子类的行为;传递任务。
public abstract class AbstractApprove {
//1.记录自己的上级是谁,方便传递任务
protected AbstractApprove abstractApprove;
public void setNextApprove(AbstractApprove abstractApprove) {
this.abstractApprove = abstractApprove;
}
//2.处理自己的审批业务
public abstract void handler(Account account);
}
- 🌹经理: 经理在审批完成之后还需要把审批转给下一级部门经理。
public class Manage extends AbstractApprove{
// 在处理自己的业务同时,还要把任务转给上级
@Override
public void handler(Account account) {
System.out.println("经理审批了");
if (!ObjectUtils.isEmpty(this.abstractApprove)) {
this.abstractApprove.handler(account);
}
}
}
- 🌺部门经理: 部门经理和经理一样审批然后传递任务。
public class DepartmentManager extends AbstractApprove{
// 在处理自己的业务同时,还要把任务转给上级
@Override
public void handler(Account account) {
System.out.println("部门经理审批了");
if (!ObjectUtils.isEmpty(this.abstractApprove)) {
this.abstractApprove.handler(account);
}
}
}
- 🌻总经理: 总经理就是最后一级了
public class GeneralManager extends AbstractApprove{
@Override
public void handler(Account account) {
System.out.println("总经理审批了");
if (!ObjectUtils.isEmpty(this.abstractApprove)) {
this.abstractApprove.handler(account);
}
}
}
-
🌷调用: 在调用的时候我们需要先把所有的角色
new
出来,然后需要设置每个角色的下一级是谁,否则每个角色在传递任务的时候不知道传递给谁。这里还有个
Account
对象,这个主要是用来传递数据,可以理解为任务。
public class Demo {
public static void main(String[] args) {
// 构建对象
Manage manage = new Manage();
DepartmentManager departmentManager = new DepartmentManager();
GeneralManager generalManager = new GeneralManager();
// 设置对象的下一级
manage.setNextApprove(departmentManager);
departmentManager.setNextApprove(generalManager);
// Account用来记录传递过程中的参数
Account account = new Account();
// 开始调用
manage.handler(account);
}
}
☘️3.示例优化
说起责任链,我们立马想起的就是Filter的使用方法,我们参考filter
的方式来优化一下上述写法。
上述过程存在的缺点,每个实现类不仅要实现业务,还要负责传递任务,我们把传递任务这个事情交给一个类FilterChain
来处理。
- 💐工具类: 工具类首先有一个集合,来存放所有的角色,然后提供一个方法,把所有的角色对象都加到这个集合里面。最核心的是要具备传递任务,首先接收到任务参数
account
之后,从角色集合中循环取出对象,然后调用每个对象的审批方法。
public class FilterChain {
// 用来记录审批人
private List<AbstractApprove> abstractApproveList = new ArrayList<>();
private int pos = 0;
// 添加审批人
public FilterChain addFilter (AbstractApprove abstractApprove) {
this.abstractApproveList.add(abstractApprove);
return this;
}
// 用来调用审批者,将任务依次传递给审批者
public void doFilter(Account account) {
if (pos < abstractApproveList.size()) {
AbstractApprove abstractApprove = abstractApproveList.get(pos);
pos++;
abstractApprove.handler(account, this);
}
}
}
- 🏵抽象类: 抽象类要改写一下,这里就不需要传递任务了,只需要关注审批业务了,但是需要把传递任务这个类作为参数,来负责传递任务。
public abstract class AbstractApprove {
public abstract void handler(Account account, FilterChain filterChain);
}
- 🌹经理: 经理审批了之后,传递任务就通过
FilterChain
来实现了。
public class Manage extends AbstractApprove{
@Override
public void handler(Account account, FilterChain filterChain) {
System.out.println("经理审批了");
// 把传递的活交给FilterChain
filterChain.doFilter(account);
}
}
- 🌺部门经理: 部门经理审批了之后,传递任务就通过
FilterChain
来实现了。
public class DepartmentManager extends AbstractApprove{
@Override
public void handler(Account account, FilterChain filterChain) {
System.out.println("部门经理审批了");
// 把传递的活交给FilterChain
filterChain.doFilter(account);
}
}
- 🌻总经理: 总经理审批了,按理说总经理审批了的话是不需要传递了,这里还是用工具传递了,只不过需不需要执行,其实是
FilterChain
来控制,我们可以看到在FilterChain
中所有的角色都放到集合里面了,需要不需要往下其实是看指针是否是指向了集合的最后一个元素了。
public class GeneralManager extends AbstractApprove{
@Override
public void handler(Account account, FilterChain filterChain) {
System.out.println("总经理审批了");
// 把传递的活交给FilterChain
filterChain.doFilter(account);
}
}
- 🌼调用: 这里的任务调度都是通过
FilterChain
来实现的了。
public class Demo {
public static void main(String[] args) {
// 任务
Account account = new Account();
// 任务传递链
FilterChain filterChain = new FilterChain();
// 把处理任务的角色放到传递链中
filterChain.addFilter(new Manage()).addFilter(new DepartmentManager()).addFilter(new GeneralManager());
// 执行任务
filterChain.doFilter(account);
}