引言
之前写了篇文章《轻流_用YAML风格文本表达串行&并行流程》,是看中它依据特点关系,能将批流图转为一棵以start节点开始的树。而这个转换过程,直接完成是很轻松的事情,只要明确了表达关系,可以瞬间表达出来。
比如:遵照如下约定
-
{ }表示并行执行的分支 -
[ ]表示顺序执行的节点序列

则上述批流图可以很轻易表达为[start, A, { [B1], [B2] }, C, D, { [D1, D2], [E1, E2], [F1, F2] }, K, end]
如果转为存储结构,则可以方便用程序结构来表达,达到图形即编程的效果。
只要有了这个表达树的数据结构,那么要呈现成怎样的图形效果,只需要选择好对应的展现工具软件(比如plantUml, d2等),按照它的语法规则,就可以完成效果展现------上图就是用d2生成的。
比如,可以用List存储的串行的元素,而用set来存储分支,set中的每个元素是一个list 或者嵌套的set分之。
落实问题
因为之前没怎么做过图的相关编程,因此这个转换过程在要实际落地的时候发现做起来很不顺畅。期间问qwen,让它来编程,结果不知道自己提问有问题还是怎样,经过七八轮的自我修正后,它决定余留问题并放弃继续优化。主要的问题:
- 顺序结构,总是不断嵌套,要做到扁平化很不理想;
- 然后节点的自然分配是个问题,同一个节点,在最后的树结构中出现好几次;
最后无赖至于,就自己手写码这个程序,最难的还是分析结构特点,然后纳入步骤的过程,这个事情花了好几天。
逻辑关键点
- 有向批流图,有几种节点类型:
- fork节点 -- 也就是分支节点: 如上图的A、D
- join节点 -- 也就是汇聚节点:如上图的C、K
- 开始节点、结束节点
- 普通节点-- 单进单出
- 先给节点归类,然后找出小的顺序节点顺序流
- 类型1:以fork节点开始,到join节点
- 类型2:以join节点开始,到fork节点 或 结束
- 类型3:从批流的开始节点,到fork节点 或结束
- 关键1:记录下每条路径的from、end
- 关键2:要有明确规则,不同情况下,from、end到底要不要纳入小批流
- 对这些小批流,进行归并处理(类似消消乐)
- 每个顺序流的from、end相同的,则他们是并行关系,需要进行合并,最终同一个from、end的,只能合并到一起,如上所述的一个list
- 不同顺序流建,A->...->K, K-> ...->M 这种,可以形成连线的顺序关系,要进行合并
- 最后的最后,就是一个start -> ... -> end 的这么个单一的连线图。
- 注意:合并的时候需要依据关系,来决定嵌套关系,不要随便加深这种嵌套,尽量扁平化
代码实现
作为javer,当然使用java来实现,代码放到了gitee: flowgraph-to-tree,欢迎点评指正。
约束:
- 约定1: 同一个节点,不能多进多出
- 约定2:整个批流图,必须有且仅有一个开始、结束节点
暂留缺陷:
- 对于开始节点就分支的情况,目前的实现是有缺陷的,留给聪明的您来完善吧。
小结
代码落地的过程远不如预期顺利,主要还是之前这方面的算法设计较少,等关键点捋清楚之后实现起来就相对容易了,这个东西可以作为工作,在后续需要的时候可以随时拿出来用。