责任链模式:步步为营。
文章目录
- 责任链模式:步步为营。
- 前言
- 一、责任链模式的作用
- 二、如何实现责任链
- 1 既然是责任链,那么就需要一个链路的承载体 ChainBody
- 2 责任链中每一步都是一个抽象类,因为承载体仅仅是构造链路顺序,里面不放置任何具体业务逻辑:步骤抽象类
- 3 具体步骤执行,继承步骤抽象类
- 4 开始测试
- 总结
前言
责任链模式个人认为算是设计模式中比较复杂的一个;顾名思义 责任链,这个模式的思想是: 构造一个个的,有规则的步骤,拼接为一个链路,然后执行,例如: 制作鸡蛋炒饭
第一步: 做米饭
第二步: 煎蛋
第三步: 一起炒
…
每一步有每一步骤的职责,当有需求改动的时候,可以灵活调整,例如我想放入葱花,那么只需要再加一步即可;
一、责任链模式的作用
旨在解决复杂业务逻辑的代码堆积化,使代码接口清晰;
1 将一个臃肿的业务逻辑,有序的拆分为多个子步骤,可以让逻辑更清晰,逻辑层代码简洁
2 多个步骤之间通常顺序不可变,但如果业务逻辑无先后顺序,也可以调整顺序,这样就会使得使用的时候,非常灵活,对于之后的业务变更等需求,扩展性非常好,扩展很简单;否则就要改动一个业务逻辑臃肿的代码,改动之前还要理清业务逻辑,而责任链方式,则只需要添加一步,甚至不用看其他代码,只要遵循已有原则,实现自己的业务逻辑就行了;
3 责任链构建好之后,当遇到同种业务逻辑,而执行顺序不同的时候,可以直接通过改变构架责任链的顺序,而快速实现编码;
二、如何实现责任链
例如: 我现在有一个数字,要加工,第一步加法 第二步减法 第三步乘法 ;每一步都有各自的处理逻辑,而且通常不会改变的部分,将他单独提取为一步,之后可能变动的,仅仅是顺序;
开始编码:
1 既然是责任链,那么就需要一个链路的承载体 ChainBody
@Data
public class ChainBody {
private ChainStep head;
private ChainStep tail;
public void addChainStep(ChainStep chainStep) {
if (null == head) {
head = chainStep;
tail = chainStep;
return;
}
tail.setNextStep(chainStep);
tail = chainStep;
}
public Integer start(Integer num) {
if (null != head) {
return head.handel(num);
}
return num;
}
}
1 addChainStep 这个方法就是在构造一个链路,其中 tail.setNextStep(chainStep); 就在将新增加的一个步骤,作为tail这个节点的tail
2 addChainStep 这个方法中,tail一直作为head的构造子链路的一个中间变量,然后每次tail 都是最新的一个节点,为了继续构造子链路做准备
3 start 方法是为了 开始执行责任链而存在,这里面的具体执行也是交给具体步骤类执行,这里仅仅作为一个执行入口
2 责任链中每一步都是一个抽象类,因为承载体仅仅是构造链路顺序,里面不放置任何具体业务逻辑:步骤抽象类
public abstract class ChainStep {
private ChainStep chainStep;
public void setNextStep(ChainStep chainStep) {
this.chainStep = chainStep;
}
public Integer handel(Integer num) {
Integer res = this.doHandel(num);
if (null != this.chainStep) {
res = this.chainStep.handel(res);
}
return res;
}
abstract int doHandel(Integer num);
}
1 这就是步骤抽象类,setNextStep 上文已经说到
2 handel 就是入口的延续,这里作为调度具体执行步骤的一个逻辑,当有子链路的时候(tail 不为空),那么当前节点还未结束,继续执行,直到无tail后,那么执行结束,这里相当于一个递归执行
3 doHandel 是一个抽象方法,上个方法是具体步骤调度逻辑,而这个方法就是要真正的步骤类执行了,他是一个抽象方法,也就是要交给具体的步骤类去执行具体方法;
3 具体步骤执行,继承步骤抽象类
public class Step1 extends ChainStep {
@Override
int doHandel(Integer num) {
return num + 5;
}
}
public class Step2 extends ChainStep {
@Override
int doHandel(Integer num) {
return num * 5;
}
}
public class Step3 extends ChainStep {
@Override
int doHandel(Integer num) {
return num - 2;
}
}
4 开始测试
public class Test {
public static void main(String[] args) {
ChainBody chainBody = new ChainBody();
chainBody.addChainStep(new Step1());
chainBody.addChainStep(new Step2());
chainBody.addChainStep(new Step3());
//chainBody.addChainStep(new Step1());
//chainBody.addChainStep(new Step2());
System.out.println(chainBody.start(10));
}
}
1 如果每个步骤里面的业务逻辑非常复杂,那么是不是这样的代码很简洁?
2 如果业务逻辑不相关,可以灵活调整执行顺序,灵活添加执行步骤
断点执行,查看责任链的链路
可以看到,这条完整的链路,然后根据这个链路,去递归执行;执行结果
总结
责任链的难点,在于构造责任链的链路,然后做好业务抽象,将每个业务相对独立的部分单独拆分出来,为了以后的业务变更做好预留,这样设计的代码,业务扩展性会非常好,当有新的链路增加进来,改动也会非常快,代码思路,逻辑更清晰;