链的构建方式(编排)
链的结构就是“流程图(画图)”的代码化。
画图元素:
- 链、节点(可带任务)、连接(可带条件)
画图规则(或定义):
- 一个链(Chain),会有多个节点(Node)组成。
- 一个节点(Node),会有多个连接(Link,也叫“流出连接”)连向别的节点。连接向其它节点,称为:流出连接。被其它节点连接,称为:流入连接。
- 一个链从一个 start 类型的节点开始,顺着连接(Link)流出
通俗些,就是通过 “点”(节点) + “线”(连接)来描述一个流程图结构。
1、使用配置构建(支持 json 或 yml)
- 示例1
demo1.chain.yml
(简单示例)。
id: "d1"
nodes:
- { id: "n1", type: "start", link: "n2"}
- { id: "n2", type: "execute", link: "n3", task: "System.out.println(\"hello world!\");"}
- { id: "n3", type: "end"}
- 示例2
demo2.chain.yml
(审批风格)。示例中,使用了元信息和空任务(用于触发驱动器的任务处理)。
id: "d2"
title: "请假审批"
nodes:
- { id: "s", type: "start", title: "发起人", meta: {role: "employee", form: "form1"}, link: "n1"}
- { id: "n1", type: "execute", title: "主管批", meta: {role: "tl"}, link: "g1"}
- { id: "g1", type: "exclusive", link:[
{nextId: "e"},
{nextId: "n2", title: "3天以上", condition: "day>=3"}]}
- { id: "n2", type: "execute", title: "部门经理批", meta: {role: "dm"}, link: "g2"}
- { id: "g2", type: "exclusive", link:[
{nextId: "e"},
{nextId: "n3", title: "7天以上", condition: "day>=7"}]}
- { id: "n3", type: "execute", title: "副总批", meta: {role: "vp"}, link: "e"}
- { id: "e", type: "end"}
# tl: team leader; dm: department manager; vp: vice-president
示意图:
- 示例3
demo3.chain.yml
(计算风格)。示例中,使用了"@"组件型任务
id: "d3"
title: "风控计算"
nodes:
- { id: "s", type: "start", link: "n1"}
- { id: "n1", type: "execute", title: "基本信息评分", link: "g1", task: "@base_score"}
- { id: "g1", type: "exclusive", title: "分流", link: [
{nextId: "e", title: "优质用户(评分90以上)", condition: "score > 90"},
{nextId: "n2", title: "普通用户"}]}
- { id: "n2", type: "execute", title: "电商消费评分", link: "n3", task: "@ec_score"}
- { id: "n3", type: "execute", title: "黑名单检测", link: "e", task: "@bl_score"}
- { id: "e", type: "end"}
示意图:
2、链配置的简化模式
属性简化:
- 当没有
id
属性时,会按顺序自动生成(格式示例:"n-1") - 当没有
link
属性时,会按顺序自动链接后一个节点(适合简单的链,复杂的需手动指定) - 当没有
type
属性时,缺省为execute
节点类型
节点简化:
- 当没有
type=start
节点时,按顺序第一个节点为开始节点 - 当没有
type=end
节点时,不影响执行
以上面的 “简单示例” 为例,可以简化为:
id: "d1"
nodes:
- { type: "start"}
- { task: "System.out.println(\"hello world!\");"}
- { type: "end"}
或者(更简)
id: "d1"
nodes:
- { task: "System.out.println(\"hello world!\");"}
3、使用代码构建
代码构建提供了更开放的机制,意味着可以自定义配置格式(自己解析),或者分解存放到持久层。
- 示例2(审批风格)。对就上面的配置
@Configuration
public class Demo {
@Bean
public void case1(FlowEngine flowEngine){
Chain chain = new Chain("d2", "请假审批");
chain.addNode(new NodeDecl("s", NodeType.start).title("发起人").metaPut("role", "employee").metaPut("form", "form1").linkAdd("n1"));
chain.addNode(new NodeDecl("n1", NodeType.execute).title("主管批").metaPut("role", "tl").linkAdd("g1"));
chain.addNode(new NodeDecl("g1", NodeType.exclusive)
.linkAdd("g2", l -> l.title("3天以下"))
.linkAdd("n2", l -> l.title("3天以上").condition("day>=3"))
);
chain.addNode(new NodeDecl("n2", NodeType.execute).title("部门经理批").metaPut("role", "dm").linkAdd("g2"));
chain.addNode(new NodeDecl("g2", NodeType.exclusive)
.linkAdd("e", l -> l.title("7天以下"))
.linkAdd("n3", l -> l.title("7天以上").condition("day>=7"))
);
chain.addNode(new NodeDecl("n3", NodeType.execute).title("副总批").metaPut("role", "vp").linkAdd("e"));
chain.addNode(new NodeDecl("e", NodeType.end));
//配置好后,装载到引擎
flowEngine.load(chain);
//执行
flowEngine.eval("d2", ...);
}
}
- 示例3(计算风格)。对就上面的配置
@Configuration
public class Demo {
@Bean
public void case2(FlowEngine flowEngine){
Chain chain = new Chain("d3", "风控计算");
chain.addNode(new NodeDecl("s", NodeType.start).linkAdd("n2"));
chain.addNode(new NodeDecl("n1", NodeType.execute).title("基本信息评分").linkAdd("g1").task("@base_score"));
chain.addNode(new NodeDecl("g1", NodeType.exclusive).title("分流")
.linkAdd("e", l->l.title("优质用户(评分90以上)").condition("score > 90"))
.linkAdd("n2", l->l.title("普通用户")) //没条件时,做为默认
);
chain.addNode(new NodeDecl("n2", NodeType.execute).title("电商消费评分").linkAdd("n3").task("@ec_score"));
chain.addNode(new NodeDecl("n3", NodeType.execute).title("黑名单检测").linkAdd("e").task("@bl_score"));
chain.addNode(new NodeDecl("e", NodeType.end).task("."));
//配置好后,装载到引擎
flowEngine.load(chain);
//执行
flowEngine.eval("d3", ...);
}
}