前言
这里的代码生成指的是模板代码生成,不是AI生成。模板代码生成是现代工程的核心基础设施,用户需要自己编写一个配置文件(文件内容当然要比生成的代码短得多),然后结合具体的模板生成相应代码。
解答困惑
我不知道会不会有人和我有同样的问题:
我们作为程序员不就是写代码的吗,为什么还要生成代码?
AI发展这么快,为什么不让AI来生成代码,模板代码生成有什么不可替代性?
实际上手的时候,模板代码生成的技术该怎么用,用在哪?
在腾讯实习的这段时间,项目内的代码生成工具我用的很频繁,我来谈谈对上面几个问题的理解:
为什么要用代码生成
对于很多业务来说,服务器的工作其实是重复的,一个典型的例子就是数据库的CRUD,对于一个大型游戏来说,这种类型的业务非常多,程序员的精力应该投入到涉及逻辑操作、算法实现等较为复杂的需求中,而不是投入到大量的重复劳作中去,因此代码生成显得很有必要,对于我们来说,我们只需要编写一个合适的配置文件,剩下的CRUD操作就交给模板代码去生成,一方面保证了数据库操作相关代码的稳定性,另一方面极大地节省了程序员的精力,提高开发效率。
模板代码生成的不可替代性
我们不得不承认AI发展的迅猛,但AI生成代码还不能取代模板代码生成。
AI生成的代码终究是受随机数影响的,即使我们的需求会讲的很明确,但我们仍不能保证AI生成的代码的一致性,一个最简单的例子就是变量名,同样是“目标”,AI前一次可能叫target,后一次就可能叫成goal,前一次可能叫get_num(),后一次就可能叫成num_get(),这看着都是小事,但是在程序中,这种灵活性往往是个麻烦。
模板代码生成应该怎么用,用到哪?
就像前面说的一样,模板代码最终要解决的就是程序员的重复劳作问题,那些重复性的工作不应该交给程序员来费心,就像计算机诞生的最初目的就是解决重复运算一样。
因此我们大可以讲:“哪里有重复哪里就可以用模板代码生成。”
了解模板代码生成的原理
既然模板代码生成这么好用,那它的原理一定很复杂吧?其实并不是,正相反,模板代码这个技术并不复杂,其实我们只需要了解他的原理就能实现个大概了。
组成结构
模板代码生成系统的构成其实非常简单,整个系统由配置文件、代码生成引擎、模板代码文件三个部分构成。
配置文件是模板代码生成中程序员操作最为频繁的部分,它包含了要生成的代码的关键信息,程序员在其中指定生成的类名,变量名,方法名等,并在其中指定相关的扩展选项,例如网络协议、游戏指令等内容。
模板代码文件则是模板代码生成是需要用的“地基”,它决定了要生成的代码的基本结构,包括模板类、模板变量、及包含简单逻辑的模板方法,使得生成的代码具有相关的基本功能,以供程序员使用。
代码生成引擎则是整套系统的核心,它负责把配置文件的语意进行解析,并结合模板代码文件生成目标代码。
实践
在实践部分我们会将配置文件命名为*.mcg
(Mew gull framework Code Generator)模板代码文件命名为*.tpl
(Template)文件也是代码生成中常见的模板代码扩展名,代码生成引擎则是提前编译好的可执行文件,这样能节省编译代码所用的时间,并将代码生成集成到项目编译的阶段,节省工作流程。
模板代码生成需要实现的功能:
用户提供一些.mcg
配置文件,配置文件形似C++、Java等语言,使用注解来丰富特性,举例如下:
// Base.mgfg
struct Vector3{
float x,y,z;
}
struct DateTime{
int year;
int month;
int day;
int hour;
int minite;
int second;
Action<int> onYearChg;
Action<int> onMonthChg;
Action<int> onDayChg;
Action<int> onHourChg;
Action<int> onMiniteChg;
Action<int> onSecondChg;
}
// SchoolSystem.mgfg
import Base.mgfg
class People{
[key = true] string id;
string name;
int age;
Vector3 pos;
}
class Student:People{
[key = true] string studentId;
string classRoomId;
DateTime enterTime;
DateTime guaduateTime;
}
class Teacher:People{
[key = true] string teacherId;
List<string> classRoomId;
DateTime enterTime;
[ExpressFunc]
int #Speak{
string knowledge;
}
}
class ClassRoom{
string classRoomId;
List<string> teachers;
List<string> students;
[NetFunc]
void #OnLesson{
string lessonId;
float duration;
int status;
}
}
class School{
List<string> classRoomId;
List<Teacher> teachers;
List<Student> students;
}
就像上面的代码写的那样,我们使用自定义的语法去构建一个模板文件,并用它来表示若干代码中的类、方法等,并基于此来实现一些模板化的功能。我们要做的就是创建一个tpl模板,编辑模板,根据.mcg和.tpl文件来生成目标代码。