客户端发出一个请求,链上的对象都有机会来处理这一请求,而客户端不需要知道谁是具体的处理对象。这样就实现了请求者和接受者之间的解耦,并且在客户端可以实现动态的组合职责链。使编程更有灵活性。
一、故事与图看懂责任链
1、未引入责任链
一个员工想请10天假期。(公司规定了经理权限:经理-可以审批3天,总经理-可以审批7天,老板-可以审批所有时间假期)
员工去找经理,经理说只能批3天假期让员工找总经理去
员工去找总经理,总经理说只能批7天假期让员工去找老板
员工去找老板,最后才批了假期
问题:存在沟通成本,这是一个员工,如果多个员工呢?理论上来讲员工不需要关心请假谁能批。谁能批是上面的事情。
2、引入责任链后
员工直接提交请假申请,从最低级领导开始,没法批就往上报,知道有权限批为止
二、代码实现
职位抽象类
/**
* <p>职位抽象类</p>
**/
@Data
public abstract class AbstractPosition {
/**
* 下一个职位
* */
protected AbstractPosition nextAbstractPosition;
/**
* 请假
* */
protected abstract Boolean askForLeave(Integer day);
}
经理
/**
* <p>经理</p>
**/
@Slf4j
public class Manager extends AbstractPosition {
@Override
protected Boolean askForLeave(Integer day) {
if (day <= 3) {
log.info("经理处理假期------" + day);
return true;
}
log.info("经理审批不了这个假期");
return this.nextAbstractPosition.askForLeave(day);
}
}
总经理
/**
* <p>总经理</p>
**/
@Slf4j
public class GeneralManager extends AbstractPosition {
@Override
protected Boolean askForLeave(Integer day) {
if (day <= 7) {
log.info("总经理处理假期------" + day);
return true;
}
log.info("总经理审批不了这个假期");
return this.nextAbstractPosition.askForLeave(day);
}
}
老板
/**
* <p>老板</p>
**/
@Slf4j
public class Boos extends AbstractPosition {
@Override
protected Boolean askForLeave(Integer day) {
if (day > 7) {
log.info("老板亲自处理了假期------" + day);
return true;
}
return this.nextAbstractPosition.askForLeave(day);
}
}
main
public class MainTest {
public static void main(String[] args) {
// 有个人想请假,他直接找经理(最底层的人)就行了,不需要关心谁能给他批假
Manager manager = new Manager();
GeneralManager generalManager = new GeneralManager();
Boos boos = new Boos();
manager.setNextAbstractPosition(generalManager);
generalManager.setNextAbstractPosition(boos);
manager.askForLeave(20);
System.out.println("恭喜通过审批");
}
}
三、总结
责任链是把一系列操作串行化,让各个类能够各司其职(很多时候不同的处理方法或不同的处理类型会用if else或其他方式放在一起)
责任链把请求和处理分开,请求无需关心处理方法,降低了耦合性