在之前文章《聊一聊网易轻舟(现在叫CodeWave)低代码NASL编程语言》中讲到过模型、框架和编程语言的关系,发现很多同学(包括当前团队的一些同学)在阅读后理解还是不够深刻,自我检讨在建模理论、编程语言和工具链方面讲的不够透彻,所以用今天这篇文章来做点补充,让大家了解为什么这些是构建低码平台必要知识。最后给大家总结一下构建低码平台需要掌握的更广范围的知识点。
一、从语义三角说起谈低码建模语言的设计
语义三角是由英国学者查尔斯·凯·奥格登和艾·阿·瑞恰慈在1923年出版的语义学重要著作《意义的意义》中提出的。对语义三角的简单理解:(语义)概念是对所指物的概括反映,二者是反映与被反映的一种直接联系;符号是概念的表达形式,二者是表达与被表达的一种直接联系;符号通过概念表达所指物,是一种间接联系。这里我们主要用(语义)概念和符号的区分来辅助理解低码建模语言。
1、先看低码建模语言语义(概念)的设计。
传统编程语言的语义概念(用于表达意图的表达设施)非常抽象,比如具备面向对象特性的传统编程语言通常都包含(但不限于)以下这些语义概念:类型,变量,语句,表达式、函数,类,继承,对象等,程序员可用这套基础的形式化语义概念系统描述所有的东西。实际程序开发中,程序员需要使用这些抽象语义概念(抽象的表达设施)去构建各类业务语义概念(具象的表达设施),比如用java开发的web应用程序中通常我们会创建一个User类并实例化一个User对象用来表示当前登陆用户。站在DSL角度,在传统编程语言中构建这些业务语义概念过程可以理解成构建intenal DSL过程。构建的DSL语义概念越具像,概念就会越多。好处是这些DSL语义概念更贴近业务开发者的认知模型,坏处是概念越多,整个系统的复杂度就会越高,尤其是各概念之间关系描述就会爆炸,这其实就是真实应用程序构建中复杂度的来源。所以在编程语言设计上具像有具像的好处,抽象也有抽象的价值,我们需要吸取两者之长。
低码建模语言设计跟我们为了完成一个具体业务程序开发而在传统编程语言上使用基础语义概念设计出各种业务语义概念的过程有点类似,差异在于在具体业务程序中创建的业务语义概念只能用于构建该程序,而低码建模语言中我们需要设计出一套在“特定范围”不同业务程序可以共用的语义概念。如何去设计这套语义概念呢?
首先我们要对这个“特定范围”做届定。第一种情况,如果某个行业已经有统一且强约束的标准,那建这个行业的低码建模语言就比较容易,但实际上如果是强标准那本质上这个建模语言就是这个标准的配套工具,大概率不需要我们去建。第二种情况,如果某个行业有约定俗称一些规范(非强标准),也可以指导低码建模语言的设计,比如要设计面向制造业ERP方向的低码建模语言,肯定需要有BOM相关的语义概念;如果要面向银行业务设计低码平台,应该要参考银行五级建模理论来设计语义概念。由于一旦我们做这样的设计,意味着这类建模语言的使用范围就被约束了,所以实际上这类低码平台也比较少(不过可配置的ERP系统倒是不少)。第三种情况,实际上目前市面上低码平台,还是以从程序员/架构师的视角去做低码建模语言设计的居多。即只要能用该软件架构表达的业务,都在这个“特定范围”内,以此来扩大覆盖范围寻求价值最大化。
这种通用型的低码建模语言设计通常参考三个东西,第一个参考是软件建模理论(或叫架构设计理论),比如程序员熟悉的mvc/ddd模型。如果参考mvc,那就会有数据模型、逻辑、页面的概念。如果参考ddd,就会有领域模型,聚合根、值对象,出入站适配器这些概念。在网易codewave低码建模语言设计中,我们主要参考mvc模型构建了页面,逻辑、实体(数据模型)这些语义概念,是一个典型贫血模型。恒生atom低码中我们参考ddd做了一点改进,在逻辑和数据模型之间增加了一个对象概念(表示领域模型),允许开发者构建一个充血模型。第二个参考是是软件行业内已经成熟且广泛使用的领域模型,比如BPMN2.0流程模型和BI报表模型等,对这些模型我们直接采纳或配套基础语言模型做简单改造就行。第三个参考来自传统编程语言,我们需要参考传统编程语言抽取基础语义概念。比如codewave中仍然有类型、变量、方法(函数)、表达式和基础控制语句这些语义概念,但是剔除了类、继承、扩展、反射、线程等概念。恒生低码从我负责开始就在补充这些基础的语义概念。这么做的目的一是完善基础的表达能力,二是用于降低对各类DSL语义概念及其关系理解的复杂性,比如页面跟逻辑、对象、连接器和字典之间的关系,抽象一下本质就是一个函数调用的关系。这一点就体现了我们上面提到的“在编程语言语义概念设计上具像有具像的好处,抽象也有抽象的价值,我们需要吸取两者之长”的思想。
2、再看低码建模语言表达方式(符号)的设计
首先,由于实现成本考虑,低码建模语言需要复用一些成熟的DSL,比如前端页面我们使用了开源的LowCodeEngine json schema,流程我们复用了bpmn2.0规范语言。这就使得低码建模语言天然就是一组external DSL组合。这是“符号”设计第一个影响因素。
其次,大家广泛认知的传统编程语言都是“文本型”语言,即开发者需要通过输入一行行的文本字符的方式构建程序。这约束了大家对“编程语言”的认知。实际编程语言完全可以设计成文本、图形或者文本+图形的组合,只不过这些“符号”的处理方式不一样罢了。而图形化编程正是低码的一种重要特征。我们看两者的差异。
文本型编程语言需要经过lexer和parser两个阶段将文本被处理成AST,图形化编程语言通常由图形化设计器直接输出带设计信息的一棵资源树(类AST结构)。lexer和parser被图形化设计器取代。另外低码语言实现比通用编程语言简单很多,不需要实现传统语言编译器的back-end部分,只要构建面向GPL的翻译器或者能够执行这个AST的引擎就可以。
表达方式的变化除了对设计器提出明确要求外,对工具链其他两个地方也产生了重要的影响,在下一节描述。
二、从软件工程工具链谈低码平台的系统设计
这是低码平台系统设计跟传统软件工程工具链的映射关系。有三点比较好理解,一是设计器本身从文本型编辑器变化为图形化设计器,二是物料资产中心,三是DSL的运行引擎或者出码翻译器,这三点不展开讲了。有两点容易被忽略的要讲下,一是设计器依赖的语言服务器(通常遵循LSP实现),二是应用代码仓库管理工具,这两个跟IDE设计器一样由于表达方式变化受到影响。
语言服务器协助设计器完成对用户程序的静态分析,帮助用户发现类型匹配错误、在用户编程时提供准确的编程提示能力以及查找引用、跳转定义等能力。但由于表达方式的变化,原来定位到代码行的反馈信息需要变更为定位到(带设计信息的)AST的资源节点上,然后通过图形化设计器体现出来。网易codewave和恒生atom低码都是借助typescript language server实现这个功能,大致实现逻辑参考下图。
应用代码仓库管理工具(比如git/svn)用于存储并管理应用代码。由于用图形化配置替换了文本型表达,直接投影生成带设计信息的资源树(类AST结构),如果仍然使用git或svn这种以“文本行”为管理单元的代码仓库管理工具就可能会破坏树节点或结构的完整性,使得低码应用遭到预期外且不易恢复的破坏。为了避免这种情况,我们需要构建以“资源(树节点)”为管理单元的资源仓库管理工具,并以此为基础提供低码应用的版本管理、分支管理和多人协作的能力。
从工具链的角度稍微扩展一下,低码本质上是平台工程的一种具体的产品实践,从这个角度展开,我们可以获得低码平台产品建设更多的指引,比如进一步完善应用开发、测试、部署、监控、运维全生命周期能力,完善低码引擎跟底层各种技术栈的集成对接,完善平台各种物料资源的共建共享机制;进一步建设从应用需求收集到交付的项目管理能力;建设从应用产品、项目等多维度的效率、质量的度量模型等。
总结:
综上所述,如果低码设计者对软件建模理论不理解,就无法定义能合理引导用户建模的语义概念;如果对传统编程语言理解不全面,那就无法抽取合适基础语义设施,掌握这两点才可能做好通用型低码建模语言设计。如果对软件工程工具链不了解,或对低码建模语言表达方式差异对工具链影响不了解,就难于构建出完整的低码平台系统。所以以上这些是构建企业级低码平台的必要的知识。最后附赠一张我自己整理的低码建设需要了解知识点图,与诸位共勉。