背景:我之前写过一篇文章:《Liteflow逻辑编排可视化设计》,分享了我们对LiteFlow这个规则引擎的逻辑可视化设计,而我们这个可视化项目的目标不仅仅只是实现LiteFlow的逻辑可视化,而是实现LiteFlow的逻辑可视化编排。
接下来,我将通过系列文章的形式,进行LiteFlow逻辑可视化编排设计与实现的开发经验分享。
《LiteFlow逻辑可视化编排设计与实现》会以系列文章的形式,有步骤、有重点地分享我们对LiteFlow逻辑可视化编排的实现,目前该系列文章有如下5篇:
- LiteFlow逻辑可视化编排设计与实现 01-先导篇
- LiteFlow逻辑可视化编排设计与实现 02-数据模型篇(Model)
- LiteFlow逻辑可视化编排设计与实现 03-视图呈现篇(View)
- LiteFlow逻辑可视化编排设计与实现 04-操作逻辑篇(Control)
- LiteFlow逻辑可视化编排设计与实现 05-后记篇(前端代码已开源,文末有仓库地址)
以下是《LiteFlow逻辑可视化编排设计与实现 01-先导篇》的文章正文。
01-先导篇
作为一名前端开发,我们需要特别关注的前端开发要素有三个——数据(Model)、视图(View)和逻辑(Control),即“MVC”——而在实现LiteFlow逻辑可视化编排时,我们也可以使用“MVC三要素”的知识框架来进行系统的拆解、组合、设计和实现。
- 数据模型(Model):将EL表达式的操作符(Operator)进行建模,在这个项目里,我们将EL表达式建模成了由ELNode组成的一棵树;
- 视图呈现(View):使用AntV X6的节点(Node)和边(Edge)进行ELNode的可视化呈现,即通过Nodes & Edges实现LiteFlow的逻辑可视化;
- 操作逻辑(Control):实现ELNode模型的增删改查(CRUD)操作。
我个人非常喜欢这个“MVC三要素”的知识框架,通过它、我可以很方便地进行系统的拆解和组合,所以本篇文章、以及本系列文章,都会以这个“MVC三要素”的知识框架进行分享。
在本篇先导篇中,我们先简单地过一下LiteFlow逻辑可视化编排的“MVC三要素”:
1、数据模型(Model)
LiteFlow对可执行的逻辑流程进行建模,主要包括以下2个部分:
-
1、逻辑组件(组件节点):逻辑组件类型包括:
① 顺序组件:用于THEN、WHEN;
② 分支组件:用于SWITCH、IF ...;
③ 循环组件:用于FOR、WHILE ...。 -
2、逻辑编排:通过EL表达式进行组件编排:
① 串行编排:THEN;
② 并行编排:WHEN;
③ 选择编排:SWITCH;
④ 条件编排:IF;
⑤ 循环编排:FOR、WHILE等等。
而对以上“逻辑组件”的“逻辑编排”,都是通过EL表达式来实现,比如一个EL表达式的例子:
<chain name="chain1">
THEN(
a,
WHEN(b, c, d),
e
);
</chain>
其中“THEN”和“WHEN”是EL表达式的关键字,分别表示串行编排和并行编排,而“a”“b”“c”“d”“e”则是5个逻辑组件,由此组成了一个串行和并行编排的组合——即先执行“a”组件,然后并行执行“b”“c”“d”组件,最后执行“e”组件。
而我们数据模型(Model),就是将EL表达式的操作符(Operator)进行建模:
- EL表达式:LiteFlow的逻辑编排是通过EL表达式来实现的,比如我们之前提到过的这个例子:
<chain name="chain1">
THEN(
a,
WHEN(b, c, d),
e
);
</chain>
- 树形结构:将LiteFlow进行文本拆解,我们其实能得到一个树形结构(即AST抽象语法树);
- JSON表示:我们可以把这棵树进行简化,得到一个简化版的JSON表示:
{
type: "THEN",
children: [
{ type: "NodeComponent", id: "a" },
{
type: "WHEN",
children: [
{ type: "NodeComponent", id: "b" },
{ type: "NodeComponent", id: "c" },
{ type: "NodeComponent", id: "d" },
],
},
{ type: "NodeComponent", id: "e" },
]
}
- 建立模型:经过以上步骤的分析,我们可以建立这么一个ELNode模型:
/**
* EL表达式的模型表示:数据结构本质上是一个树形结构。
* 例如一个串行编排(THEN):
{
type: ConditionTypeEnum.THEN,
children: [
{ type: NodeTypeEnum.COMMON, id: 'a' },
{ type: NodeTypeEnum.COMMON, id: 'b' },
{ type: NodeTypeEnum.COMMON, id: 'c' },
{ type: NodeTypeEnum.COMMON, id: 'd' },
],
}
*/
export default abstract class ELNode {
// 节点类型:可以是编排类型,也可以是组件类型
public type: ConditionTypeEnum | NodeTypeEnum;
// 当前节点的子节点:编排类型有子节点,组件类型没有子节点
public children?: ELNode[];
// 当前节点的父节点
public parent?: ELNode;
// 判断类节点类型:主要用于SWITCH/IF/FOR/WHILE等编排类型
public condition?: ELNode;
// 组件节点的id
public id?: string;
// 编排节点的属性:可以设置id/tag等等
public properties?: Properties;
}
2、视图呈现(View)
在实现LiteFlow逻辑可视化编排时,我们使用的图编辑引擎是AntV X6——不光因为它足够好用、我们很常用,而且我们用起来也挺有心得,感兴趣的朋友可以看我之前写的文章:「AntV X6」从5个核心要素出发,快速上手AntV X6图可视化编排。
我们目前初步实现了LiteFlow的以下3类/6种逻辑可视化:
- 1、顺序类:串行编排(THEN)、并行编排(WHEN);
- 2、分支类:选择编排(SWITCH)、条件编排(IF);
- 3、循环类:FOR循环、WHILE循环。
我之前写过一篇文章:《Liteflow逻辑编排可视化设计》,感兴趣的朋友可以先看一看。
3、操作逻辑(Control)
LiteFlow的逻辑可视化编排,主要是实现对ELNode模型的增删改查操作:
为了方便使用,我们不光实现了通过拖拽(Drag & Drop)添加节点,而且在画布中也实现了通过快捷面板(ContextPad),在节点和边上快速新增节点。
而针对ELNode的“增删改查”,我们可以在ELNode中通过定义如下相应的方法进行实现:
export default abstract class ELNode {
/////// 接着上面步骤 1.数据模型(Model)
/**
* 添加子节点
* @param child 子节点
* @param index 指定位置
*/
public appendChild(child: ELNode, index?: number);
/**
* 删除指定的子节点
* @param child 子节点
*/
public removeChild(child: ELNode): boolean;
/**
* 创建新的节点
* @param parent 父节点
*/
public create(parent: ELNode, type?: NodeTypeEnum): ELNode
/**
* 删除当前节点
*/
public remove(): boolean;
/**
* 转换为X6的图数据格式
*/
public toCells(
previous?: Node,
cells?: Cell[],
options?: Record<string, any>,
): Cell[] | Node;
/**
* 转换为EL表达式字符串
*/
public toEL(): string;
}
以上是我们《LiteFlow逻辑可视化编排设计与实现 01-先导篇》的内容,是我们接下来系列文章的一个概览,希望能帮到有同样需求的朋友。