我对于无代码编程的研究也有些年头了,从国内最早的『无代码编程』相关的文章,到最近的『流程即代码:云研发 IDE Uncode』,我大抵是有资格再聊聊这个行业。
最近,我们 Inherd 开源小组推出了『云研发 IDE:Uncode』的预览版,然后便与不同企业的人进行了一波的交流。在这些观点的驱动之下,我觉得我们有必要再写一些文章:好好介绍一下一些相关的理念。这些理念用于帮助这些企业,好好思考一下研发平台的下一站。
再谈云开发平台
对于开发平台来说,转身为一个云开发的平台,是行业内的一个大趋势。这也就是为什么国内的各大云厂商都在兜售它们的平台。从我与他们的交流情况来看,尽管它们自称有一个“完整”的平台,但是客户只买单其中的一两个。其中的原因颇多,其中的一些主要原因是:
企业自身已经开发/采购一部分环节的工具、产品。
平台本身缺乏足够的亮点。
而位于其背后的主要原因,我个人的观点是:它对于效能的提升是极小的、有限的。这些平台缺乏一个完整的回路,以提升整体的体系与交通。
1. 平台没有『闭环』
首先,让我们来看某国内领先的云公司的案例。它们宣称:通过整合云原生产品和云效,完成了云原生开发闭环。其所谓的闭环是,它们有:
在线协同工具
代码托管工具
在线 IDE
在线构建
在线部署
在线运维
然后,他们宣称这是闭环。嗯,作为一个工程师,我在大学是学过自动化相关的课程,所谓的闭环是:
闭环(闭环结构)也叫反馈控制系统,是将系统输出量的测量值与所期望的给定值相比较,由此产生一个偏差信号,利用此偏差信号进行调节控制,使输出值尽量接近于期望值。
简单来说,闭环的一个重要标志是:输出改进输入。而闭环本身又分为整体闭环和链路闭环:
整体闭环:系统的线上运营指标,可以指导需求的创建。
链路闭环:系统的两两之间可以形成闭环,加快反馈回路。如代码的修改,可以反馈到设计和需求。
所以,回到上述这个案例里,如果要完成整体的闭环,它还需要加入在线运营的环节,才能完成整体闭环。
2. 工具间的割裂
对于这一点,我相信大家都有体验。我这里主要以云厂商和大型 IT 团队为例:
云厂商单工具可零售
继续以国内的云厂商为例,它们为了让企业能用上自己的云服务,便上线了大量的研发相关的工具,如云 IDE、看板、代码托管等等。它们存在的一个问题是,为了卖出更多的云服务,每个工具本身是可单独售卖的,所以每个工具本身是包含大量的可定制元素。也因此,这个系统中的每一部分都相当的臃肿,更难以形成一个完整的方案。
如果基于这些云服务、工具去构建一个开发平台 ,那么它将带来 M ^ N 的复杂度。反而不如,推出一个一体化的版本更为容易。
大型企业工具部门墙
作为一个技术咨询师,我在内部材料、咨询项目中见过大量的平台和工具。它们有着大量的重复性的工具,还有着工具间的隔离问题。如 A 团队开发了一个工具 a,而 B 团队开发了一个工具 b,这两个工具相结合可以创造出更大的生产力。但是,你懂的,他们出于部门墙的缘故,往往难以结合到一起。
3. 还有,开发者的体验呢?
这是另外一个大话题。(有兴趣可以读一读『开发者体验 —— 内部工具的“最后一公里”』。)
一个常见的问题是:在设计工具的时候,由于面向领导的需求,往往面向使用者考虑的优先级会低于领导使用时的优先级。
低代码对于研发平台意味着什么?
在这里,我把研发平台和低代码做了一个简单的绑定,其中的缘由是:人们对于低代码的实践和思考,必然会引发下一步对于研发平台的改造。
低代码平台的意义:流程优化的思考
对于当前流行的拖拉拽低代码平台,我提不起任何的兴趣。在整体方案上,我喜欢于构建基于 DSL 的低代码平台。在这一篇文章里,我不展开对于这两者的讨论。
不论是拖拉拽低代码平台,还是 DSL 低代码,它们让越来越多的开发人员、管理者开始思考一个问题:如何优化当前的流程?
低代码是从需求到线上代码的直接转换,作为平台的用户,他们本身理解真实的需求,可以作为直接的创作人员。在流程上,它省略了需求电子化,需求转换为验收条件的一系列过程,与此同时,它还可以让应用直接上线。整个过程中,它大大加速了应用的设计和开发过程。
那么,作为一个企业的研发平台,我们也理所应当的加速当前的这个流程。
研发工具一体化
基于云研发和低代码的思路,我们定义了第一个版本的研发工具一体化:
研发工具一体化,即构建从需求、设计、编码、构建、测试等完整研发体系的研发工具上的链路闭环。链路内的两个结点相互影响、相互关联,如系统的需求的创建将关联到设计的创建,设计的完成将生成对应的代码生成。在完成整体的闭环时,代码的变更将影响到设计的变更和需求的变更等。
即,我们要做这么两件事:
形成工具间的反馈回路。
完善工具间的关联设计和用户体验。
基于这两个目标,我们能:
在看板上创建一个需求时,可以将其与设计进行关联。
完成模型设计时,可以自动生成代码到代码库中。
完成 UI 设计时,可以生成代码到代码库中。
代码库的模型发生变化时,将自动变更 UI 设计和模型设计。
这就是我们当前在 Uncode IDE 做的事情。
与研发中台的关系
正是人们建立了后端服务的中台,促使人们在构建低代码平台时,拥有一个强有力的技术后盾。同样对于研发体系也是如此,在中台热潮里,人们定义了『研发中台』:
软件开发是一项工程,涉及到管理、流程、测试、团队协作等等方面。如何将企业的开发流程、最佳实践沉淀成可重用的“能力”,从而助力创新性应用的快速开发迭代,也是我们看到的很多企业正在做的事情,我们可以管这种关注开发效能管理的平台叫作研发中台。
对于那些已经建设研发中台的组织来说,它们可以进一步往前进了。
研发工具一体化的难点
要搞研发工具一体化并不是一件容易的事情,毕竟我设计了这么多年,才有了个大概的雏形。从企业来说,这些痛点主要是:
组织内的部门墙
缺少代码专家
KPI 制度难以驱动长期目标
……
与此同时,这个市场上并没有一个可以参考的成功案例。
构建研发工具一体化的核心
对于研发工具一体化来说,我们关注于两个点:
抽象设计,即 DSL@Core。使用特定的语言来描述工具,以确保工具与具体实现无关。
反馈设计。即系统的所有输出能影响到输入层面,用于确保各步骤的一致性。
抽象设计:DSL@Core
借助于抽象,而非具体实现,DSL(domain specific language,领域特定语言)就这样的一种模式。如在《云研发:研发即代码》中,我们引入了一系列代码化的方式,用于描述不同环节的抽象。
当然了,设计一个使用自然语言描述的 DSL 不是一件容易的事情。为此,我们可以数据描述的 DSL,如在低代码平台流行的 JSON Schema,类似的还有 Database Schema。
使用何种形式的 DSL 并不重要的,重要的是用它来描述流程与设计。如我们可以用 BDD 的方式来描述需求:
Given I visit "/login"
When I enter "Bob" in the "user name" field
And I enter "tester" in the "password" field
And I press the "login" button
Then I should see the "welcome" page
再将其转换为 UI 设计的 DSL:
flow 登录 {
SEE 首页
DO [Click] "登录".Button
REACT Success: SHOW "Login Success".Toast with ANIMATE(bounce)
REACT Failure: SHOW "Login Failure".Dialog
SEE "登录失败".窗口
DO [Click] "忘记密码".Button
REACT: GOTO ForgotPasswordPage
}
以诸如此类的方式作为中间承载类,完善整个系统的设计。
PS:如果你对这一系列 DSL 有兴趣,可以参与到 Inherd 开源小组的一系列开源软件中来:https://github.com/inherd
反馈式设计
在设计需求、设计、代码时,我们使用 DSL 来隔离实现。在实现之后,我们需要对实现进行分析,看其是否与设计出现偏离。因此,我们要进行反馈式设计。
如在架构上我们可以采用 守护式编程 / 限制性编程。当设计与代码不对应,则修改设计。需求与代码不对应,则修改代码。如下是我们基于 ArchUnit 设计的适用于主流语言的架构守护的 DSL:
class(implementation "Connection.class")::name should endsWith "Connection";
class(extends "Connection.class")::name endsWith "Connection";
class(assignable "EntityManager.class") resideIn package("..persistence.");
这里我们定义了一系列包、类等的访问规则,随后在提交阶段,通过对代码的分析来看代码是否出现架构上的越界?一旦访问了规则限制的 DSL,则限制其提交代码。
又比如,我们在 Uncode 中引入了 modeling
分析工具,将代码中的模型关联到设计模型中,以判断模型是否偏离原有的设计,并进行调整。
其它
就时间而言,现在并非是建立研发工具一体化的最好时间。但是,是时候采取对其的预研。
欢迎与我们进行交流。
相关阅读资料:
https://github.com/inherd/uncode
https://github.com/phodal/lowcode
https://github.com/phodal/cloud-dev
https://github.com/phodal/water/