仅以此文总结一下团队在低代码平台建设中犯过的错,如果能对其他低代码同仁有帮助,那便再好不过了。
虚拟表vs实体表
平台从诞生起就具备了可视化建模的能力,但在早期阶段,我们以"虚拟表 "存储对象和字段。
"虚拟表 "意味着数据对象与数据库中的表并不一定存在对应关系,该对象在数据库中可能以一条记录的形式存在。数据对象的字段也同样并不对应某张数据库表的若干个字段,也可能是某几条记录。
这个设计的好处是,对象和对象字段的新增/修改,都不必执行DDL。在查询侧,我们基于Manticore开发了一套查询引擎sdk,并对部分类型字段的查询做了性能优化。这也要求所有开发者们即便二开,也只能通过这套sdk实现增删改查。
在实践中,这套设计遇到了一些非常重要的挑战。第一个是运维需求 ,因为整个数据库和表都是黑盒 ,所以平台必须要提供完善的数据运维能力,并且开发者只能通过平台进行数据运维。另一个是性能,零售行业的一些大型公司每年都能产生千万级甚至亿级数据量,并且表结构复杂,字段多(一些关键表能放数百个字段),关联关系复杂,这已经远远超出了平台最初设计的场景了。
因此平台后续针对数据存储和查询引擎进行了一次重大重构,每个数据对象都对应一张实体表 。数据对象和字段的增删改,会经过版本diff生成DDL ,发布后运行时服务动态执行该DDL。
当然这个设计也会引入一些不足,比如部分开发者直接在数据库更改了字段,那么平台在生成差异DDL时可能会出现问题。但相比前面的黑盒模式,产线上更接受这个方案。
id关联外键vs任意字段逻辑关联
对象间的关联关系,平台的实现方案是对明细对象增加一个字段表示其关联的主对象,比如人员和公司存在多对一关系,那么在人员对象上增加一个隐藏字段关系code.id
,表示该人员关联的公司id。主查询明细则查询明细对象的关系code.id=主对象的id
; 明细查询主则查询主对象的id=关系code.id
。
这种设计虽然难以实现多对多关系,但大多数场景下的查询都能得到支持------《万能查询契约设计》。
这个方案在对接外部系统时问题很多:
- 外部对象无法实现关联查询。按照该方案,平台对象关联外部对象存的是该对象的id,并且关联查询时,也是根据id关联查询,而外部对象不一定会提供id字段,强行对第三方提要求并不现实。
- 对接外部数据,导入到系统后,按照平台的模式,需要将原字段关联表示的数据,改为id关联,这也不现实。
外键实际开发中很少使用了,都是在代码层面逻辑关联,并且绝大多数只有在编辑时才会进行关联查询。针对外部系统或外部对象,我的设想是在前端层面支持逻辑关联并作字段映射。

前端工作流vs整体工作流
平台最初提供的工作流,是基于前端视角抽象出来的。
从前端视角看,会有如下典型的工作流场景:
基于该场景抽象,按钮的点击事件是一个工作流 ,发送请求/打开或关闭弹窗/消息提示/刷新页面这些是工作流的action ,可以通过可视化逻辑编排完成;弹窗内的表单是可视化搭建 ;整个工作流内部可以通过变量/自定义函数/逻辑网关等方式完成特定业务需求。
最终我们是基于这套抽象出来的模式提供了可视化逻辑编排和自定义视图搭建,在业务处理并不复杂的时候能很好地满足需求。
这套方案的缺点在于,前端视角往往是基于界面交互,而非业务链路。
因此在这套方案下,很多实践不得不分别从前端视角和后端视角,将业务链路拆成一个个弹窗和接口 ,然后让前端一步一步展示弹窗或调用接口。这样的工作流很难复用,更专业的说法叫"无法资产化"。
并且有些复杂的业务逻辑,对前端来说就是一个接口,但对后端来说,可能是一系列调用流程。
比如一个导入,可能包括了:excel解析------数据清洗------数据新增/修改------发送通知。
为了满足后端的逻辑编排的诉求,平台又基于后端的常见action提供了一套工作流。于是平台做出了两套工作流,虽然平台支持在前端工作流中调用后端工作流,但并没有解决真正的,基于业务视角的逻辑编排的问题。
无状态工作流vs有状态工作流
无状态的工作流是指没有实例的工作流,而有状态工作流每次执行会创建一个工作流实例 。前者类似一个函数,后者是函数+状态机。
无状态的好处是实现简单,不会涉及到工作流数据的保存------所有数据在工作流执行生命周期内产生,并在执行结束后销毁。
缺点也很明显。
如果工作流需要前后端交替执行,那么就必须确保全量上下文数据的和完整工作流schema的传递,这对复杂工作流来说是个灾难。通常无状态的工作流根本不会考虑交替执行的场景------它们都是不可中断的。
另外,开发者需要自行维护一个状态机或状态字段,后端提供修改状态的工作流或接口,并让前端分步串起整个流程。
另外,这里还有个小插曲。为了减轻开发者负担,团队甚至提供了状态机按钮 : 状态机绑定数据对象------按钮绑定状态机。这样按钮能自动根据数据状态切换点击文案和点击功能,这显然是在错误的道路上越走越远了。
总之,工作流的设计,要保证业务逻辑的流畅性和完整性------碎片化的工作流无法复用。
配置式视图搭建vs拖拽式视图搭建
我们最初提供了配置式搭建,即根据数据对象直接生成列表/表单/按钮。缺点是不支持自定义布局和非标页面。因此我们提供了类似宜搭那种拖拽式可视化页面搭建。
如果考虑到商业化后的更广泛场景,拖拽式可视化搭建有其必要性。但考虑到公司的绝大多数场景,配置式搭建,无论是效率还是易用性,都远超过拖拽这种交互。尤其是列表这种复杂页面,很难通过多个组件拖拽拼装出来。
最终团队的实现是,将配置式列表页面当成一个可视化搭建的一个组件。对通过可视化搭建的丰富组件+事件/代码/变量等,实现对表格单元格内特殊ui需求的支持。
但在公司的实践中,这套方案对产线的开发者来说,操作难度太高。我始终认为,与其让用户拖拽+代码,不如让列表对应区块直接支持多种ui组件的配置,免去代码的编写。
AI
从今天看,低代码的发展一定得结合AI才能有未来,但当时的AI相关生态和技术并不成熟。低代码与AI的结合,并不是简单部署一个模型就能实现的。
以我粗浅的想法,可能会是这样一种设计。
