作者: 扬远
云凤蝶是蚂蚁的建站平台,云凤蝶中台应用使用带自由拖拽功能的 IDE 制作页面,内置了 Ant Design、AntV、TechUI 等 UI 资产,内建大量最佳实践等,让开发者快速开发出高质量中台应用。
低代码是什么?
现在业界低代码的概念犹如当年的 H5 一样被炒的火热,但低代码平台到底该具备什么特质呢?是只要少些代码就是低代码了么?
本文主要探讨我心中的低代码平台的特质以及云凤蝶平台在低代码方面的一些探索。
可视化设计器
可视化设计器在低代码领域可谓是必备功能,为什么大家一提到低代码第一印象就是可视化设计器?
对于程序员来说,程序算法虽然比较抽象,但是是描述机器执行的过程,用流程图、伪代码还是可以表达,无非就是算法/工程角度的优劣而已。但 UI 他不讲逻辑,如果用代码来描述将会是 “页面左上角 x:8, y:8 有一个宽高 100 的容器”、“容器内有一个红色警告按钮”,如果涉及到视口自适应,还会加入层级结构、宽高类型等概念,变的更为复杂,很多时候只有跑起来才知道是否符合预期,对非专业前端/客户端的开发来说不容易上手。
可视化设计器通过所见即所得的形式大大降低了 UI 布局的上手门槛,提升 UI 的开发效率,不过,回顾整个应用开发领域,可视化设计器可谓是历史悠久,从早到 1995 年的 Delphi,到后来的 WinForm(2002)、Flex(2004)、WPF(2006) 等等,可视化设计器的体验越来越好,并不是新东西。可见,可视化设计器本身很难作为与 ProCode 对比的独特优势,在应用开发领域,拖拖拽拽还经常处于鄙视链底端。
Delphi 7 (左), WinForm (右)
BaaS 服务/服务集成
平台提供一体化的后端服务以及服务集成能力应该是集成开发平台最吸引人的特性。平台可以一站式使用各种服务端能力,不需要再去开通服务,并进行配置。宇宙 IDE Visual Studio 与 Azure 深度集成,可以直接操作 Azure 中的服务、资源,体验非常好,比如可以自动收集应用性能、埋点数据的 Application Insights。再看特定领域的传统软件,CRM、ERP、OA 类的软件都历史悠久,无论是自建版还是 SaaS 云版也提供了服务集成,配套服务也一样可以服务于 ProCode。
当然,以上只是说可视化设计器和服务集成不是低代码与 ProCode 相比差异化的优势,并不是说这些不重要。相反,这些功能是非常重要的研发提效手段,而且也不仅限提到的这两方面能力。
第四代编程语言
C++/C#/Java/JavaScript 等被视为第三代编程语言(3GL),3GL 隐藏了机器码、中断等概念,代码量有数量级的减少,从对机器友好转变为对程序员友好,开发的效率也有了本质提升。
第四代编程语言(4GL)被定义为非过程编程语言(声明性语言),比如 SQL,作为其中一种在数据处理方面与第三代相比抽象程度更高,当然,代码量比 3GL 也有明显减少,效率自然提升明显。
低代码平台也符合 4GL 的特点——抽象层级更高、代码量更少、效率更高,所以低代码开发环境也被算入了 4GL。提取其中的关键点:
- 声明性,隐藏过程,表达抽象需求,从高层抽象的一到低层级的多,是减少代码量,提升效率的根本。
- 语言,语法、结构、糖,语法简洁,结构清晰,含糖量适中。其实语法糖就有简化作用,就是在一定领域的更高层级的抽象。而 4GL 代表的应该是成体系的、完整的抽象。SQL 就是很好的例子,SQL 作为 DSL(领域专用语言)不再描述具体的数据库操作过程,而是直接表达数据需求。
低代码相比于 ProCode 来说核心的提效思路就在于领域抽象,这是最根本的底层逻辑,低代码想要有代差的提效,就需要在领域范围内,相对于 ProCode 提供更高层级的抽象,隐藏具体的实现细节。基于这个逻辑,低代码平台做可视化设计、服务集成、前后端逻辑混排、多端发布等等,都是自然而然的选择。而抽象的完善程度决定了低代码平台的能力上限。
云凤蝶的探索
布局系统
对于低代码平台来说,可视化搭建是最重要的核心能力,画布能力的上限直接关系到操作体验和最终产出的页面效果。特别是前端的 CSS 是不正交的,对于没有 UI 开发经验的开发者来说想要快速开发出符合要求的 UI 难度很高。
在布局方面,云凤蝶针对中后台场景做了抽象和简化,主要支持两种布局方案,自由布局和弹性布局。
自由布局
自由布局结合了绝对定位和相对定位的优点,在编辑时类似绝对定位,更符合直觉,用户可以随意摆放,但不支持组件重叠覆盖。而在渲染时则会根据布局信息划分行列并进行渲染,这样可以保留相对定位适配内容、自动伸缩尺寸的特性。
弹性布局
有些场景对元素具体位置并不十分关心,只需保证相对位置,或者是一个列表,元素的个数是动态的,这时候使用自由布局就变的麻烦了。所以云凤蝶还提供了与前端 Flex 一致的弹性布局方式,可以快速实现表单、列表等场景。
不足
1、布局
我们目前的布局系统有三种布局类型,自由布局、弹性布局和静态布局,其中静态布局的含义是,虽然是一个容器类型的组件,但容器部分样式行为由组件自己控制,在系统层面没有配置项。对用户来说主要是自由布局和弹性布局。
从需求出发,使用弹性布局主要的场景在于无需关心具体的尺寸、可以自动挤占以及不定子元素个数的情况下自动折行折列。这两个特性有没有可能纳入到自由布局体系下呢?
自动挤占
其实自由布局在运行时是能做到的,自由布局在运行时不是绝对定位,而是相对定位。主要问题在于编辑时联动调整的能力比较弱,我们在规划中也有自适应调整布局的功能,如果可以在编辑时做到自动挤占,那么这个场景是否就可以不使用弹性布局了?
折行折列
这个问题与自动挤占类似,自由布局实际上也有一定的折行折列的能力,如果在编辑时也提供完整的布局关联调整的能力,整体来看也有覆盖弹性布局这一场景的可能性。
目前粗略的统计,弹性布局占 37%,其中表单场景占了不少。总体来说,如果我们的自由布局能够健壮,不再需要再定义一个弹性布局的话,对用户来说就消减了一个概念、一个决策点,甚至不再需要感知弹性这个事情都是有可能的。
2、交互
我们通过布局系统解决了静态设计问题,但对于交互——动态设计,我们没有提供更多支持,我们提供的是最基础的,数据驱动的概念,让用户通过修改数据来控制视图变化。
在交互方面,业界其实已经有了不少实践,比如 Flash、WPF(Blend)。这两个技术栈在视图方面都有状态的概念,并且支持可视化录制,页面的视图状态可以看做是是一个状态机,交互是触发源,驱动着状态机流转。
功能角度来说,有了状态的概念,也可以用于设计师的分镜和讲稿功能。而从开发用户角度来讲,页面交互就可以直观的表述为从 A -> B 的状态转移,提供了一个范式,只要搞清楚转移条件、转移方程就可以了。
小结
云凤蝶在布局方面最大的特点是有一套自由布局体系。自由布局是在中后台建站场景下大部分布局需求的抽象,在编辑时采用符合直觉的类似绝对定位的方式,而在运行时又通过算法按照合理的相对对位的方式进行渲染。可以让用户不再关心到底是该先做一个行还是列容器。
逻辑代码
云凤蝶提供的是数据驱动的开发模式,主要围绕页面模型展开,用户可在页面模型上定义属性、方法,并从视图进行绑定,围绕页面模型还提供了连接器(HTTP API、TR)、模型服务、NPM 导入模块等。
由于使用了 TypeScript,配合语法解析和规范限制,使得我们对用户代码有了一定的理解能力,比如可以分析用户页面模型的变量,在写订阅时提供类型支持,提供 decorator 可以标识自定义组件对外暴露属性等。
随着需求越来越复杂,逻辑代码从最开始的纯 Model 变为 ViewModel,加入了全局逻辑、页面逻辑、组件(绑定)逻辑、交互逻辑、NPM 体系等概念。
不足
云凤蝶的主要用户至少都有一定的编程能力,对于相关的概念,能够快速学习上手,数据驱动、双向绑定的方案,对于用户来说还是比较直观,有一定提效的。但这方面与 ProCode 基本一致,对用户暴露的概念与 ProCode 类似,这就意味着使用成本、学习成本也是 ProCode 级的,有没有什么方式可以更好的提效呢?
可视化流程编排
提效一定不是简单的换一种展示方式,如果只是将编程语言的语法可视化,那只是可视化编程,与底层编程语言最大的不同就在于语法不同。如果底层是 C++ 之类的语言,可能还有一定的降低门槛的作用,但如果是高级语言、解释型语言,优势就有限了,毕竟对于编程逻辑能力的要求是一致的。
举个例子:经常会有数据处理的场景,需要将数组中每项的某字段做映射,映射一般是一个函数,会用到多 if,或者 switch,写这个函数是完成映射需求必须的么?如果提供映射的面板(语法糖),是不是就不需要了?
虽然对应程序员来说,数据映射函数太简单了,感觉没啥必要,但这个的底层逻辑不是必不必要,而是需不需要,用户可以不需要这很重要。Python,我们说他是胶水语言,优势是可以很方便的调用其他语言提供的模块,生态也非常丰富,如果所有的需求都有提供,写 python 的时候是不是也有低代码的感觉呢?
mendix 的流程编排
回到云凤蝶的角度,前面也说到,云凤蝶的用户编程能力要更强些,所以要不要去掉/屏蔽底层语言语法不怎么重要,思路上也需要结合目前用户的使用方式,可以去分析用户用代码编写的逻辑,抽出代码结构而不是一一映射,生成流程图,物料方面,封装的功能可以生成到代码被用户代码使用,从优先有基础的开发者的角度慢慢演进。
小结
由于将 NPM 包引入到了整个用户代码体系,使我们的代码能力达到与 ProCode 无异。但这也是一把双刃剑,过渡使用代码会降低我们对用户代码的理解以及掌控能力,而且作为低代码平台,如果因为能力不完备而过多使用代码实现(绕过)是我们不希望看到的。
资产体系
对于可视化搭建来说,物料体系直接影响功能需求是否可以实现、视觉还原的效果,以及决定了平台整体的可用性。
在物料数量方面,云凤蝶提供了 npm 导入能力,可以直接使用绝大部分 React 组件库。云凤蝶对组件的要求非常少,组件的对接改造成本极低。
组件属性
云凤蝶可以通过对 TypeScript 定义解析来提取组件属性,并且支持 renderProps、ReactNode、function 等特殊类型的属性,能力上与 ProCode 对齐,并且对 ProCode 代码无侵入。
属性上来说,除了支持组件自身定义的属性,云凤蝶在平台层面还提供了一些通用能力,比如重复、条件渲染、跳转、锚点等。
资产包
针对组件等的跨应用复用需求,云凤蝶提供了资产包机制,可以完成跨应用公共资产的管理。我们默认也提供了涵盖基础组件、业务组件、图表库三方面,中后台场景下最常用的资产包。
资产包与普通应用的区别是没有全局逻辑和配置,没有部署,取而代之的是发布。
资产包采用激进的升级策略,会保证依赖资产包的站点及时升级到最新版,而资产包的不兼容更新就要靠开发者来保证。针对资产包云凤蝶也提供了 codemod 机制,赋予开发者自动化调整使用方应用站点数据的能力。
不足
在资产方面,物料的数量和质量至关重要,由于支持无侵入的 React 组件导入体系,可以很方便的复用 React 社区资产,以及与 antd 团队的紧密合作,也保证了资产能力上覆盖的复杂度。
针对 ProCode 开发的 React 组件虽然功能强大,但也意味着易用性方面就不太如人意。虽然云凤蝶也支持了组件可以配置多套预设值以供消费时选择,但配置项带来的原生复杂度没有消解。如何兼得功能完备性和易用性还需要后续进一步探索。
后端能力
1、搭建服务 - 数据升级
随着业务发展,领域模型的演进,不可避免的会遇到对基础模型不兼容改造的场景,所以底层数据模型的可升级是非常重要的。云凤蝶采用比较激进的方式,只持续迭代最新版本,在出现数据层面不兼容变更时,使用 codemod 的形式升级到最新版本。
⚠️ 应用数据分为 应用基础数据(标题、团队、部署模式等)和 应用资源数据(编辑器、运行时消费的资源数据),数据升级主要针对 应用资源数据。
要想保证 Codemod 机制可以有效运行,Codemod 及应用相关的所有数据都需要遵循一定的规则:
后端不感知数据结构
如果数据有不兼容版本,则对数据消费的整条链路都需要区分版本,而后端分版本建立集群不合算也不现实,所以需要将数据的消费都集中在前端,后端不能独立解析数据结构,如果确实有需要,则可以通过 Computing 机制来读取数据。
应用数据完整性
与编辑时、运行时相关的所有资源数据都需要存储到资源内部,而不能只保留一个引用。
2、运行时服务
云凤蝶还提供了服务端能力,可以支持无服务端资源的业务快速上线,替代 BFF 层。并且还提供了数据链接能力,可以链接到 TR、HTTP API、MySQL、OceanBase。对于需要数据存储的场景还可以使用模型服务快速建模,函数服务也在开发中。
智能向导
云凤蝶智能向导功能是针对中后台最常用的表格、表单、详情场景的抽象。可以通过配置式快速开发相应的功能页面。
默认好用
智能向导本质上是一个专家系统,有着非常复杂的规则树,支持数据驱动和 UI 驱动两种使用模式。采用策略模式从组件推断、视图编排、视觉规范、逻辑/数据匹配等多个维度进行推荐、生成,也支持用户二次修改自定义配置,目前这个模块已有 4.8w+ 代码。
部分规则树
智能向导之所以提效就在于我们对表格、表单、详情以及对应设计规则这些特定领域内的理解。使用户无需关心实现对应功能页面具体的操作过程,不需要使用平台基础语法(操作)去实现对应功能。
智能向导虽然是自动生成页面组件,但也有着可以高度还原设计的能力,这就得益于我们底层技术栈在高可用方面的努力。在能力层面我们力求 ProCode 一致,所以智能向导的产物理论上也可以涵盖绝大部分需求。特殊的定制需求也可以对产物进行打散然后二次编辑开发。
规则定制
默认的智能向导组件内置的是我们总结适合大部分场景的规则,但在具体的业务线可能会有一些特定的规则。针对这种情况,我们也提供了智能向导引擎能力,可以自定义智能向导的生成规则,以符合业务线的惯例。
小结
虽然智能向导越来越强大也越来越好用,但从云凤蝶的架构上来说,目前只是在产品层,我们还在探索如何把这套方法沉淀下来,指导覆盖到更多场景。难点在于如何找到适合抽象的场景,以及如何辅助提效的套路。
另一方面来说,目前智能向导的规则库也越来越庞大,规则的扩展和管理也需要找到更好的方式。从应用整体来看,类似 lint、autofix 的规则机制来做开发管控也是一种提效思路。
结语
在我的心中,目前研发有两大类方式,ProCode 和 LowCode,ProCode 主要在于使用第三代语言以及配套技术栈研发,而 LowCode 对应用开发领域抽象,形成自治、完备的 DSL 体系,NoCode 是 LowCode 的一种理想情况,本质上与 LowCode 一致。
ProCode 与 LowCode 相辅相成,LowCode 体系比如物料等方面一定也需要 ProCode 的支持,只是在特定领域 LowCode 的研发效率应该比 ProCode 有明显的提升。
可视化设计、服务集成、后端能力等等并不是 LowCode 专属,自然,靠这些产品层面的功能不足以支撑代差级的提效。SQL 是非常好的例子,SQL 的提效不在于是否有强大的编辑工具、支持各种关系数据库,SQL 提效的内核是抽象了合理的 DSL,外围的产品功能都是水到渠成的选择,SQL 还使得数据相关专业不在需要专业的软件开发知识,也改变了相关领域的上手门槛和工作流程。LowCode 也应该达到相同的水平,如何在效率方面做出代差,云凤蝶还有很长的路要走,还需要我们进一步的探索和努力。
看到上面那一堆堆的不足了么?如果有对云凤蝶、低代码平台感兴趣的同学欢迎交流: zhenyang.zzy@antfin.com。我们的目标是要在研发效能方面做出代差,这需要我们进一步的探索和努力。