代码生成模式:未来我们会怎样写代码?

这篇文章的草稿差不多在我的 todo 列表里躺了一年,直到最近,看到我的同事在吐槽手动创建步骤的繁琐性。我才想起来,我曾经想写一篇这样的文章,但是我在我的博客( https://www.phodal.com ) 上找了好久,也没有发现。然后,我终于在我的 To-Do 应用中看到了它的身影。
虽然说是模式总结,到底只是个人经验。受限于个人经验,可能有些许的不足之处。若是各位读者愿意指出来,那自然感激不尽。

开发过程:IDE 代码片段『精选』

IDE 代码片段『精选』即在 IDE/编辑器中,通过插件或者内置组件,对特定语言、框架、技术等提供自动化的代码填写。
代码集这个东西,自然比较是比较有意思的。在我们的日常开发中,我们经常会使用到,它的名字有多样多样,如

  • AutoComplete
  • Snippets
  • 智能感知
  • ……

它倒也没有什么特别之处,在我们输入一些词的时候,给我们建议,如在 IDE 里输入 list.for
,过程中就可以生成如下的代码:

for (item in list) {

}

嗯,就这么简单,是不是经常使用到。

开发过程:语言、框架抽象 DSL

语言抽象 DSL,即通过编辑器、IDE 内置对于语言和框架的抽象,使开发人员可以通过编写 DSL 便可以生成特定语言的代码。

它特别适合于编写简单的模板代码,如 HTML、XML 等。作为一个开发人员,那么最常看到的例子就是 Zen Coding/Emmet,这个东西非常炫,输入 ul>li*5>a[href="#"]
,然后按一下 tab,你就可以快速生成如下的代码:

嗯,它特定适合于编写结构化的代码格式。

创建时:模板化代码生成

模板化代码生成,即在代码 or IDE 中内置特定系统、团队的代码范式,随后通过特定的参数,来生成适合于该团队和该系统的代码。

考虑到前端领域创建模板的复杂性,创建的过程中,需要同时创建 *.component.scss
*.component.spec.ts
*.compnent.ts
*.component.html
,所以在前端领域非常之流行。最简单来说,Angular 开发人员通过 ng g
就可以生成各式各样的代码。

事实上,我觉得对应于后端开发也是如此,毕竟创建一个 CRUD API 可能需要 model
repository
api
service
等。不过,依我的观察来看,后端开发人员一般都没有 GET 到这项技能,因为 gradle 太 TM 难用了。
尽管,大部分框架都自带了类似的生成器,但是大多数时候,都得自己撸一个适合于架构的模板。所以,这里推荐一下适用于前后端的框架。

Angular Schematics

Schematics 是前端开发工作流工具,例如:创建一个组件、变更配置项至当前项目,并且不限制任何语言环境。

Plop

Plop 是一个微型生成器框架。它提供了一种以一致的方式生成代码或任何其他类型的纯文本文件的简单方法。
嗯,这两个框架,大家自己了解一下。

创建时:DSL 生成代码

DSL 生成代码,顾名思义就是通过 DSL 的方式,来生成代码,再集成到系统中开发。
最常见的一个例子就是我最近使用基于 Antlr 编写的 Chapi,便是这种模式。又或者是,对于一些模式化的开发的系统来说,它们也是通过类似的方式来生成大量的模板。
注意:通过这种模式生成的代码,往往是不会进行二次开发的。因为随着引擎的更新,这些代码会被覆盖住,导致难以维护。

如 Antlr 这样的框架,只需要通过: antlr -Dlanguage=Java -listener -visitor CPP.g4 -o chapi/ast/antlr -package chapi.ast.antlr
编译生成到指定的目录。于是乎,我们就可以 import chapi.ast.antlr
,集成到系统中使用。

构建时:DSL / 代码生成代码

构建时代码生成代码,即在构建的时候,才进行代码生成。
对于稳定的系统来说,可以只在构建时才运行代码生成。平时的时候,都是通过生成临时代码的方式。嗯,常见的 Angular 框架就是类似的方式运行的。
在开发的过程中,我们都是通过编码 DSL 或者是一种不同于最终运行语言来编写的。

运行时:元编程

元编程(Metaprogramming)是指某类计算机程序的编写,这类计算机程序编写或者操纵其他程序(或者自身)作为它们的数据,或者在运行时完成部分本应在编译时完成的工作。
这一点大家都很熟了,我就不再重复描述了。

未来

随着,无代码编程/低代码编程越来越流行,代码生成的基础架构来越来越火。