使用计算链框架编程并实现"把大象塞冰箱"

简介

把大象塞冰箱,一共分几步?小品里面的答案是三步,第一步:把冰箱门打开,第二步:把大象塞进去,第三部:把冰箱门关上。
这里我们开一下脑洞,把这个问题抽象成Java程序,使用计算链来拆分这几个步骤,将每一步单独制作成一个计算器,从而实现一个大象塞冰箱工程。

设计

这里使用上一篇博客介绍的计算链框架,新建工程并定义若干计算器,最后调用计算链实现大象塞冰箱的功能。

程序流程图:

核心代码

引入依赖

1
2
3
4
5
<dependency>
<groupId>com.github.johnsonmoon</groupId>
<artifactId>calculate-chain</artifactId>
<version>1.0.0</version>
</dependency>

结构

1
2
3
4
5
6
7
8
9
10
11
|- elephant-refrigerator
|- src
|- main
|- java
|- xxx.xxx.xxx
|- actions
|- Step1.java 步骤一
|- Step2.java 步骤二
|- Step3.java 步骤三
|- ActionContext.java 上下文
|- Main.java 程序入口

源码

上下文

ActionContext.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
import java.util.ArrayList;
import java.util.List;

public class ActionContext {
private Boolean done = false;//完成否
private Integer step = 0;//步骤
private Integer stepCount = 0;//步骤总数
private List<String> stepMessages = new ArrayList<>();//步骤消息

public ActionContext stepCount(Integer stepCount) {
this.stepCount = stepCount;
return this;
}

public void addStep(String message) {
step++;
if (step >= stepCount) {
done = true;
}
stepMessages.add(message);
}

public Boolean getDone() {
return done;
}

public List<String> getStepMessages() {
return stepMessages;
}

@Override
public String toString() {
return "ActionContext{" +
"done=" + done +
", step=" + step +
", stepCount=" + stepCount +
", stepMessages=" + stepMessages +
'}';
}
}

步骤一

Step1.java

1
2
3
4
5
6
7
8
9
10
11
12
import com.example.elephant.refrigerator.ActionContext;
import com.github.johnsonmoon.calculate.chain.annotation.Calculate;
import com.github.johnsonmoon.calculate.chain.calculator.Calculator;

@Calculate(order = 1, contextType = ActionContext.class)
public class Step1 implements Calculator<ActionContext> {
@Override
public ActionContext doCalculate(ActionContext actionContext) {
actionContext.addStep("第一步:把冰箱门打开");
return actionContext;
}
}

步骤二

Step2.java

1
2
3
4
5
6
7
8
9
10
11
12
import com.example.elephant.refrigerator.ActionContext;
import com.github.johnsonmoon.calculate.chain.annotation.Calculate;
import com.github.johnsonmoon.calculate.chain.calculator.Calculator;

@Calculate(order = 2, contextType = ActionContext.class)
public class Step2 implements Calculator<ActionContext> {
@Override
public ActionContext doCalculate(ActionContext actionContext) {
actionContext.addStep("第二步:把大象塞进去");
return actionContext;
}
}

步骤三

Step3.java

1
2
3
4
5
6
7
8
9
10
11
12
import com.example.elephant.refrigerator.ActionContext;
import com.github.johnsonmoon.calculate.chain.annotation.Calculate;
import com.github.johnsonmoon.calculate.chain.calculator.Calculator;

@Calculate(order = 3, contextType = ActionContext.class)
public class Step3 implements Calculator<ActionContext> {
@Override
public ActionContext doCalculate(ActionContext actionContext) {
actionContext.addStep("第三部:把冰箱门关上");
return actionContext;
}
}

程序入口

Main.java

1
2
3
4
5
6
7
8
9
10
11
12
13
import com.github.johnsonmoon.calculate.chain.CalculatorChain;

import java.util.List;

public class Main {
public static void main(String[] args) {
ActionContext context = CalculatorChain.doCalculate(new ActionContext().stepCount(3));
boolean done = context.getDone();
System.out.println("执行完毕否: " + done);
List<String> steps = context.getStepMessages();
steps.forEach(System.out::println);
}
}

运行结果

1
2
3
4
执行完毕否: true
第一步:把冰箱门打开
第二步:把大象塞进去
第三部:把冰箱门关上