计算链(流水线)算法设计及其实现框架

简介

在一些实际业务场景中,我们需要将一个大的操作分解成前后依赖的小操作;或者将一系列具有先后顺序的同类操作管理起来依次执行;
例如在汽车总装车间中,组装流水线的若干工位需要对上一个工位传递的产品输出进行修饰装配,然后传递给下一个装配工位,
最终流水线产出一辆整车产品。类似于这样的具有流水线性质的操作,我们可以将其抽象为一个计算链,
通过计算链中的若干个”计算器”或者称其为”计算步骤”,将大操作简化为单个小计算步骤的操作,来实现复杂的计算过程。
计算器(计算步骤)之间相互隔离,单个计算器依赖的是前者的输出,并对该输入执行对应的修饰并将其输出。

设计

计算链初始化流程图:
image

计算链执行计算流程图:
image

核心代码片段

计算链调度方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

public static <CONTEXT> CONTEXT doCalculate(CONTEXT context) {
String contextKey = context.getClass().getCanonicalName();
List<Calculator> chain = calculatorChainMapCache.get(contextKey);
if (chain != null && !chain.isEmpty()) {
for (Calculator calculator : chain) {
try {
context = (CONTEXT) calculator.doCalculate(context);
} catch (Exception e) {
logger.warn(e.getMessage(), e);
}
}
}
return context;
}

说明:

  • 调度方法根据传参从计算链缓存获取指定处理类型的计算链
  • 调度方法遍历执行计算链内的计算器
  • 计算链初始化过程中已经根据计算器属性进行优先级排序

用法示例

示例代码结构

1
2
3
4
5
6
7
|- src
|- com.xxx.xxx.xxx
|- calculator
|- Calculator1.java
|- Calculator2.java
|- Calculator3.java
|- Test.java

示例代码

Calculator1.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import com.github.johnsonmoon.calculate.chain.calculator.AbstractCalculator;

public class Calculator1 extends AbstractCalculator<Integer> {
@Override
public Class<Integer> contextType() {
return Integer.class;
}

@Override
public int order() {
return 3;
}

@Override
public Integer doCalculate(Integer integer) {
System.out.println(contextType().getSimpleName() + " calculator " + Calculator1.class.getSimpleName() + " order " + order());
return integer + 1;
}
}

Calculator2.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import com.github.johnsonmoon.calculate.chain.calculator.AbstractCalculator;

public class Calculator2 extends AbstractCalculator<Integer> {
@Override
public Class<Integer> contextType() {
return Integer.class;
}

@Override
public int order() {
return 2;
}

@Override
public Integer doCalculate(Integer integer) {
System.out.println(contextType().getSimpleName() + " calculator " + Calculator2.class.getSimpleName() + " order " + order());
return integer + 1;
}
}

Calculator3.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import com.github.johnsonmoon.calculate.chain.calculator.AbstractCalculator;

public class Calculator3 extends AbstractCalculator<Integer> {
@Override
public Class<Integer> contextType() {
return Integer.class;
}

@Override
public int order() {
return 1;
}

@Override
public Integer doCalculate(Integer integer) {
System.out.println(contextType().getSimpleName() + " calculator " + Calculator3.class.getSimpleName() + " order " + order());
return integer + 1;
}
}

Test.java

1
2
3
4
5
public class Test {
public static void main(String[] args) {
System.out.println(CalculatorChain.doCalculate(0));
}
}

运行结果

1
2
3
4
Integer calculator Calculator3 order 1
Integer calculator Calculator2 order 2
Integer calculator Calculator1 order 3
3

代码仓库

https://github.com/johnsonmoon/calculate-chain.git