Corellis代码生成工具:从声明式DSL到自动化样板代码实践

发布时间:2026/5/15 23:23:19

Corellis代码生成工具:从声明式DSL到自动化样板代码实践 1. 项目概述与核心价值最近在开源社区里一个名为 Corellis 的项目引起了我的注意。它不是一个全新的编程语言也不是一个庞大的框架而是一个专注于“代码生成”的轻量级、高性能工具。简单来说Corellis 的核心目标是让你用更少的代码做更多的事并且做得更快、更可靠。它通过解析你的代码结构理解你的意图然后自动生成那些重复、繁琐但又必不可少的“样板代码”。想象一下每次新建一个数据模型你都需要手动编写对应的序列化/反序列化方法、数据库映射代码、甚至是基础的 CRUD 接口。这些工作技术含量不高但极其耗时且容易出错。Corellis 就是为了解决这类问题而生的。我最初接触它是因为在一个需要快速迭代的后端服务项目中我们团队被大量重复的实体类定义、DTO转换和API文档编写拖慢了进度。手动维护这些代码不仅效率低下一旦业务逻辑变更同步更新所有相关代码更是一场噩梦。Corellis 的出现让我们看到了自动化这些流程的可能性。它不是一个“魔法棒”而是一个“代码工匠的得力助手”通过一套定义良好的规则和模板将开发者从重复劳动中解放出来让他们能更专注于核心业务逻辑和创新。这个项目适合任何厌倦了编写重复代码的开发者无论是前端、后端还是全栈。如果你经常需要处理数据模型、API接口、配置文件生成等任务Corellis 值得你花时间深入了解。它不试图取代你的思考而是放大你的产出效率。2. 整体设计与核心思路拆解2.1 核心理念从“手写”到“生成”Corellis 的设计哲学非常清晰声明优于指令生成优于复制。传统开发中我们通过一行行代码“指令”计算机去完成特定任务。而 Corellis 鼓励你先“声明”你想要什么——比如一个具有特定字段的用户模型、一个遵循 RESTful 规范的增删改查接口。然后由 Corellis 根据这些声明自动“生成”出完整、规范且可运行的代码。这种转变带来的好处是巨大的。首先它保证了代码的一致性。所有生成的代码都遵循同一套模板和规则避免了不同开发者手写带来的风格差异和潜在错误。其次它极大地提升了可维护性。当业务规则变化时你只需要更新核心的声明比如数据模型然后重新运行生成命令所有依赖的代码如DTO、API层、数据库访问层都会自动同步更新避免了漏改、错改的风险。2.2 架构解析三驾马车驱动为了实现上述理念Corellis 的架构主要围绕三个核心组件构建解析器Parser、模板引擎Template Engine和生成器Generator。这三者协同工作构成了代码生成的完整流水线。解析器负责读取和理解你的“声明”。这些声明通常以特定的领域特定语言DSL、注解Annotation或结构化的配置文件如YAML、JSON的形式存在。例如你可能会在一个user.model.crl文件里定义用户模型的字段和类型。解析器的任务就是将这些声明解析成 Corellis 内部能够理解的抽象语法树AST或中间表示IR。它的健壮性直接决定了工具能否准确理解你的意图。模板引擎是 Corellis 的“灵魂”。它定义了代码最终长什么样。模板通常是用类似 Mustache、Handlebars 或 Corellis 自有的模板语言编写的文本文件其中包含占位符和控制逻辑。解析器产生的数据模型AST/IR会作为上下文注入到模板引擎中。引擎根据模板逻辑进行渲染将占位符替换为具体的代码片段。一个设计良好的模板库是 Corellis 是否好用的关键。它需要足够灵活以支持不同编程语言、不同框架的代码风格。生成器是最终的执行者。它协调解析和模板渲染的过程并决定将生成的代码输出到哪个文件、哪个目录。生成器还负责处理文件系统的操作比如检查目标文件是否存在、是否覆盖、以及如何组织生成代码的目录结构。一些高级的生成器还可能集成到构建工具如Maven、Gradle、Webpack中实现编译时或运行时的自动生成。注意不要将 Corellis 与那些通过AI猜测你意图的代码补全工具混淆。Corellis 是确定性的它的输出完全由你的输入声明和模板决定是可预测、可重复的。这既是优点稳定、可靠也要求使用者必须清晰地定义输入。2.3 方案选型背后的考量为什么选择“模板生成”这条路径而不是其他如“元编程”或“运行时反射”1. 编译时安全与性能生成的代码在编译时就已经是完整的源代码可以被编译器如Javac, TypeScript Compiler, Go Compiler完整地检查类型、语法和语义错误。这比运行时通过反射动态生成和调用代码要安全得多性能也更好因为不存在反射开销。2. 语言和框架中立模板引擎可以与任何编程语言结合。只要你能为这种语言编写模板Corellis 就能为其生成代码。这使得它能够轻松适配 Java Spring Boot、TypeScript NestJS、Go Gin、Python FastAPI 等各种技术栈而不需要修改核心引擎。3. 可读性和可调试性生成的代码是纯文本文件开发者可以直接阅读、理解和调试。如果生成的结果有问题你可以直接查看生成的源代码定位问题是在模板还是输入声明上。这比调试复杂的元编程逻辑或运行时字节码操作要直观得多。4. 易于定制和扩展团队可以根据自身的编码规范和项目结构定制专属的模板。当需要支持一种新的代码模式时编写一个新模板往往比修改核心生成逻辑要简单快捷。3. 核心细节解析与实操要点3.1 声明式输入定义你的“蓝图”Corellis 的威力始于一份清晰的“蓝图”。这份蓝图即你的输入声明需要精确描述你希望生成什么。常见的声明方式有以下几种各有优劣1. 自定义DSL文件这是最强大、最灵活的方式。你可以设计一门简化的语言专门用于描述领域模型。例如Corellis 项目本身可能就定义了一种.crl(Corellis) 文件格式。// 示例一个简单的用户模型DSL entity User { id: Long Id GeneratedValue username: String NotBlank Unique email: String Email createdAt: LocalDateTime status: UserStatus // Enum } endpoint /api/users { operations: [GET, POST, PUT, DELETE] response: UserDTO }这种方式分离度最高但需要学习一门新的“语言”并且要为其编写解析器。2. 利用语言原生注解对于像 Java使用注解、C#使用特性这类语言这是非常自然的方式。你可以在现有的实体类上添加 Corellis 能识别的注解。// 示例使用注解声明 CorellisEntity public class User { CorellisId GeneratedValue private Long id; CorellisField(notBlank true, unique true) private String username; CorellisField(format email) private String email; // ... getters and setters }优点是无缝集成到现有代码开发者熟悉。缺点是污染了业务模型代码且受限于宿主语言的注解表达能力。3. 结构化配置文件YAML/JSON这是一种折中的方案易于阅读和编写且被广泛支持。# models/user.yaml User: fields: id: type: long constraints: [primary, auto_increment] username: type: string constraints: [not_blank, unique] email: type: string format: emailYAML/JSON 的缺点是缺乏复杂的逻辑表达能力但对于大多数模型定义来说已经足够。实操心得对于新项目或希望严格分离“声明”与“实现”的团队推荐使用自定义DSL或独立的YAML配置。对于改造现有项目使用注解可能是侵入性最小的方式。关键在于团队要统一约定并坚持使用一种方式。3.2 模板引擎塑造代码的“模具”模板决定了代码的“长相”。Corellis 的模板引擎需要能够处理变量替换、条件判断、循环迭代等基本逻辑。一个典型的模板文件例如用于生成 Java Entity 的entity.java.hbs可能如下所示// {{entity.name}}.java package {{entity.package}}; import javax.persistence.*; import java.time.LocalDateTime; {{#if entity.hasEnums}} {{#each entity.imports}} import {{this}}; {{/each}} {{/if}} Entity Table(name {{entity.tableName}}) public class {{entity.name}} { {{#each entity.fields}} Column(name {{this.columnName}}) {{#if this.isId}} Id GeneratedValue(strategy GenerationType.IDENTITY) {{/if}} {{#if this.isUnique}} UniqueConstraint {{/if}} private {{this.type}} {{this.name}}; {{/each}} // 默认构造器 public {{entity.name}}() {} // Getter 和 Setter {{#each entity.fields}} public {{this.type}} get{{capitalize this.name}}() { return this.{{this.name}}; } public void set{{capitalize this.name}}({{this.type}} {{this.name}}) { this.{{this.name}} {{this.name}}; } {{/each}} }在这个模板中{{ ... }}是变量占位符{{#if}}、{{#each}}是控制逻辑。entity对象就是从解析器传来的数据模型。模板设计的核心原则单一职责一个模板只负责生成一种类型的文件如Entity、DTO、Controller。可配置化通过模板参数或全局配置控制生成的细节比如是否生成 Lombok 注解、使用哪种日期库。符合团队规范生成的代码风格缩进、命名、注释必须与团队现有规范一致。3.3 生成策略与文件组织生成器不仅负责渲染模板还要管理输出。这里有几个关键决策点1. 覆盖 vs 合并当目标文件已存在时是直接覆盖还是尝试合并对于源代码通常建议覆盖因为生成的代码是完整的、一致的。对于配置文件如pom.xml的依赖部分可能需要更智能的合并策略。Corellis 通常提供命令行参数如--force来控制这一行为。2. 目录结构映射如何将逻辑模型映射到物理文件路径通常通过配置来定义。例如output: mappings: - when: type Entity template: templates/entity.java.hbs output: src/main/java/{{packagePath}}/{{name}}.java - when: type Controller template: templates/rest-controller.java.hbs output: src/main/java/{{packagePath}}/controller/{{name}}Controller.java这样一个com.example.model.User实体就会生成到src/main/java/com/example/model/User.java。3. 增量生成与缓存为了提高效率生成器应该支持增量生成。即只有当输入声明或模板文件发生变化时才重新生成对应的输出文件。这通常通过计算文件哈希来实现。4. 实操过程与核心环节实现4.1 环境准备与快速开始假设我们想在一個 Spring Boot 项目中试用 Corellis 来自动生成 JPA 实体和 Spring MVC 控制器。第一步安装 Corellis CLICorellis 通常提供一个命令行工具。最便捷的方式是通过包管理器安装如果官方提供。例如假设可以通过 npm 安装npm install -g corellis/cli或者直接下载其发布的可执行 Jar 包curl -L -o corellis.jar https://github.com/CorellisOrg/Corellis/releases/latest/download/corellis-cli.jar第二步初始化项目结构在你的项目根目录下创建一个corellis文件夹用于存放所有声明文件和模板。my-spring-project/ ├── src/ │ └── main/ │ └── java/ ├── corellis/ │ ├── models/ # 存放模型声明文件 (.yaml) │ ├── templates/ # 存放自定义模板 (.hbs) │ └── config.yaml # Corellis 主配置文件 └── pom.xml第三步编写模型声明在corellis/models/下创建user.yaml:name: User package: com.example.demo.entity tableName: t_user fields: - name: id type: Long primaryKey: true autoIncrement: true - name: username type: String notNull: true unique: true maxLength: 50 - name: email type: String notNull: true format: email - name: createdAt type: LocalDateTime default: now第四步编写或获取模板你可以从 Corellis 社区获取针对 Spring Boot 的官方模板包或者自己编写。将模板文件如entity.java.hbs,repository.java.hbs,controller.java.hbs放入corellis/templates/。第五步配置生成规则编辑corellis/config.yaml:input: dir: ./models format: yaml templates: dir: ./templates output: baseDir: ../src/main/java mappings: - when: true # 对所有模型都应用 template: entity.java.hbs output: {{packagePath}}/{{name}}.java - when: {{generateRepository}} template: repository.java.hbs output: {{packagePath}}/repository/{{name}}Repository.java - when: {{generateController}} template: controller.java.hbs output: {{packagePath}}/controller/{{name}}Controller.java globalVars: generateRepository: true generateController: true第六步执行生成命令在项目根目录下运行corellis generate -c corellis/config.yaml或者如果使用 Jar 包java -jar corellis.jar generate -c corellis/config.yaml如果一切顺利你将在src/main/java/com/example/demo/entity/下看到生成的User.java在repository/和controller/子目录下看到对应的 Repository 和 Controller 文件。4.2 自定义模板进阶处理复杂逻辑官方模板可能不完全符合你的需求。这时就需要自定义。假设我们不想用 Lombok而是想生成完整的 Getter/Setter并且想为每个字段添加 Swagger 注解。修改entity.java.hbs模板package {{package}}; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import javax.persistence.*; import java.time.LocalDateTime; Entity Table(name {{tableName}}) ApiModel({{name}}实体) public class {{name}} { {{#each fields}} Column(name {{columnName this.name}}, nullable {{this.notNull}} {{#if this.unique}}, unique true{{/if}}) {{#if this.primaryKey}} Id GeneratedValue(strategy GenerationType.IDENTITY) {{/if}} ApiModelProperty(value {{this.description}}, {{#if this.primaryKey}}required true{{/if}}) private {{this.type}} {{this.name}}; {{/each}} // 默认构造器 public {{name}}() {} // Getter 和 Setter {{#each fields}} public {{this.type}} get{{capitalize this.name}}() { return this.{{this.name}}; } public void set{{capitalize this.name}}({{this.type}} {{this.name}}) { this.{{this.name}} {{this.name}}; } {{/each}} // 辅助方法将字段名转换为下划线风格的列名 {{#*inline columnName}} {{#camelCaseToSnakeCase this}}{{/camelCaseToSnakeCase}} {{/inline}} }这个模板做了几件事1. 引入了 Swagger 注解。2. 根据字段属性动态生成Column注解的nullable和unique参数。3. 添加了ApiModelProperty注解。4. 通过自定义的 Helper 函数camelCaseToSnakeCase需要在 Corellis 配置或模板引擎中注册将字段名转为下划线列名。实操心得编写复杂模板时务必先在少量模型上测试。可以利用 Corellis 的--dry-run或--preview参数预览生成结果而不实际写入文件避免覆盖重要内容。4.3 集成到构建流程实现自动化手动运行生成命令容易忘记理想的方式是将其集成到项目构建生命周期中。对于 Maven 项目可以使用exec-maven-plugin在generate-sources阶段执行 Corellisbuild plugins plugin groupIdorg.codehaus.mojo/groupId artifactIdexec-maven-plugin/artifactId version3.1.0/version executions execution idgenerate-corellis-sources/id phasegenerate-sources/phase goals goalexec/goal /goals configuration executablecorellis/executable !-- 或 java -- arguments argumentgenerate/argument argument-c/argument argument${project.basedir}/corellis/config.yaml/argument /arguments /configuration /execution /executions /plugin /plugins /build这样每次执行mvn compile时都会自动先运行代码生成。对于 Gradle 项目可以创建一个自定义的 Tasktask generateCorellis(type: Exec) { workingDir project.rootDir commandLine corellis, generate, -c, corellis/config.yaml } // 确保在编译Java任务前运行此任务 compileJava.dependsOn generateCorellis集成后团队任何成员拉取代码后只需执行标准的构建命令就能获得最新、一致的生成代码确保了开发环境的一致性。5. 常见问题与排查技巧实录在实际引入和使用 Corellis 的过程中你肯定会遇到各种问题。下面是我和团队踩过的一些坑以及解决方法。5.1 生成代码不符合预期这是最常见的问题。排查思路应该像调试程序一样层层递进。1. 检查输入声明首先确认你的模型声明文件YAML/DSL语法是否正确字段名、类型、属性是否与模板期望的匹配。一个常见的错误是 YAML 缩进不对导致解析失败。可以使用在线的 YAML 校验器或yaml-lint工具先检查文件。2. 检查模板上下文数据模板渲染错误往往是因为传入的数据结构不对。Corellis 通常提供一个调试模式来输出解析后的中间数据。例如运行corellis parse model.yaml --debug来查看解析器到底输出了什么数据结构。对比这个数据结构和你模板中引用的变量路径如{{entity.fields.0.name}}是否一致。3. 检查模板逻辑特别是条件判断{{#if}}和循环{{#each}}。确保条件表达式能正确求值为布尔值。在 Handlebars 中空数组、null、undefined、false、0、空字符串都会被判定为false这可能导致你期望的循环没有执行。在模板中临时添加{{log this}}或{{debugger}}取决于模板引擎支持来输出变量值。4. 检查输出路径确认config.yaml中的输出路径映射规则是否正确。特别是{{packagePath}}这类变量它是否被正确转换成了文件路径如将.替换为/。5.2 性能问题生成速度慢当模型数量很多上百个时生成速度可能变慢。优化策略启用增量生成确保 Corellis 配置或命令行开启了增量生成模式。它应该只处理有变动的声明文件。简化模板过于复杂的模板逻辑如嵌套多层循环、在模板内进行复杂计算会拖慢渲染。尽量将计算逻辑移到解析器或生成器阶段让模板只做简单的变量替换和展示。并行生成检查 Corellis 是否支持并行处理多个模型。如果支持可以在配置中调整并发线程数。如果不支持可以考虑将模型分组用脚本并行调用多个 Corellis 进程。缓存模板编译结果如果 Corellis 每次都要从磁盘读取并编译模板这会是个瓶颈。可以查看是否有配置能将编译好的模板缓存在内存中。5.3 与现有代码的冲突和合并场景你生成了一个UserController.java但后来手动在其中添加了一些复杂的业务逻辑。现在模型User新增了一个字段phoneNumber你需要重新生成 Controller。直接覆盖会丢失手动添加的逻辑。解决方案生成到隔离区域不要直接生成到主源代码目录。可以配置生成到一个临时目录如target/generated-sources/corellis然后将生成的代码与手动编写的代码通过继承、组合或 Mixin 的方式关联起来。例如生成的UserControllerBase包含基础的 CRUD 方法手写的UserController继承它并添加业务方法。这样重新生成只会覆盖基类子类不受影响。使用“部分生成”或“补丁”一些高级的代码生成工具支持只生成方法的“骨架”如空的方法体或者识别出代码中的特定标记如// GENERATED CODE START...// GENERATED CODE END只覆盖标记之间的内容。你需要检查 Corellis 是否支持类似特性或者通过定制模板来实现。严格的代码分区约定这是最实用但也最依赖团队纪律的方法。约定所有生成的代码文件都不可手动修改。任何定制都必须通过其他方式实现比如生成一个UserService接口和其基础实现UserServiceImplBase然后创建一个UserServiceImpl来继承基础实现并覆盖方法或者通过 AOP 切面来添加横切关注点逻辑。5.4 版本管理与团队协作生成的代码是否应该提交到版本库如 Git两种主流观点提交生成代码优点构建过程简单不需要每个开发者都安装和配置 Corellis 环境。CI/CD 流程也无需额外步骤。代码库是自包含的。缺点版本库会变得臃肿。当声明文件更改时会看到大量生成的代码文件变更使 Code Review 变得困难。容易发生冲突特别是多人同时修改声明文件时。不提交生成代码优点版本库干净只包含“源代码”即声明文件和模板。变更历史清晰。缺点每个开发者都需要正确安装和配置 Corellis。CI/CD 流程中必须加入生成步骤。如果生成过程有非确定性因素极少见可能导致不同环境生成的代码不一致。我的建议对于内部依赖强、稳定性要求高的生成代码如根据 Protobuf 生成的 gRPC 客户端/服务端代码可以考虑提交以简化开发和部署。对于频繁变动、属于业务逻辑一部分的生成代码如 CRUD 控制器不建议提交。而是将代码生成作为编译前的一个强制步骤通过完善的文档和自动化脚本如项目根目录的setup.sh或init命令来保证团队环境一致。5.5 调试与日志当生成过程出现神秘错误时详细的日志是救命稻草。确保开启详细日志运行 Corellis 时使用-v或--verbose标志。这通常会输出解析、模板加载、渲染、文件写入等各个阶段的详细信息。理解错误信息Corellis 的错误信息可能来自多个层面声明文件解析错误类似“YAML syntax error at line 10, column 5”。直接定位到源文件修改。模板渲染错误类似“Missing helper: capitalize”。说明模板中调用了一个未注册的辅助函数你需要检查模板配置或提供这个函数。文件系统错误如“Permission denied”或“Directory does not exist”。检查输出目录的权限和路径是否正确。建立一个最小可复现案例当遇到复杂问题时尝试创建一个最小的、只包含问题模型的声明文件和最简单的模板单独运行生成。这能帮你快速隔离问题是出在 Corellis 工具本身、你的配置还是某个特定的模板逻辑上。6. 扩展应用与高级玩法Corellis 的基础用法是生成数据模型和API层代码但其潜力远不止于此。一旦你掌握了其核心机制就可以将其应用到软件开发的各个角落。6.1 生成基础设施即代码IaC配置在现代云原生开发中基础设施配置如 Dockerfile, Kubernetes YAML, Terraform 脚本也是代码并且同样存在大量重复模式。你可以用 Corellis 来生成它们。场景为每个微服务生成统一的 Dockerfile 和 Kubernetes Deployment 配置。声明创建一个service.yaml声明服务名称、端口、环境变量、资源需求CPU/内存、镜像仓库地址等。name: user-service port: 8080 env: - name: DB_URL valueFrom: configMap - name: LOG_LEVEL value: INFO resources: requests: memory: 512Mi cpu: 250m limits: memory: 1Gi cpu: 500m image: my-registry.com/apps/user-service:latest模板编写Dockerfile.hbs和deployment.yaml.hbs模板将上述变量填充进去。生成运行 Corellis为每个服务生成一套标准的、符合公司规范的部署配置大大减少了手动编写和复制粘贴带来的错误。6.2 生成前端代码与类型定义前后端协作中保持 API 接口和数据类型同步是一个痛点。Corellis 可以成为前后端的“契约中心”。流程在后端项目中使用 Corellis 的某种声明格式如 OpenAPI/Swagger 的简化版定义 API 接口和数据类型。运行 Corellis生成后端Spring Boot 的 Controller、Service 接口、DTO 类。前端TypeScript 的接口定义interface User { ... }、API 客户端函数使用 axios 或 fetch 的封装、甚至 React/Vue 组件的 Props 类型。将生成的前端代码发布到一个 npm 包或直接复制到前端项目中。这样当前端需要调用GET /api/users/{id}时他们可以直接使用生成的getUserById(id: number): PromiseUser函数和User类型无需手动查阅文档或担心类型不匹配。6.3 自定义代码质量检查与规范生成你可以编写模板来生成代码质量相关的配置或者直接生成“规范代码”作为对比基准。示例生成 Checkstyle 或 PMD 规则文件。 如果你的团队有一套复杂的编码规范手动维护 XML 格式的规则文件很麻烦。你可以用更简洁的 YAML 定义规则然后用 Corellis 生成对应的checkstyle.xml或pmd-ruleset.xml。当规范更新时只需修改 YAML 并重新生成即可。示例生成“黄金标准”代码片段。 对于团队内经常讨论的“如何正确实现分页查询”、“如何编写线程安全的单例”等问题你可以将这些最佳实践写成 Corellis 模板。当有新成员加入或开启新项目时运行生成命令就能得到一份符合团队标准的示例代码作为学习和参考的起点。6.4 与领域驱动设计DDD结合在 DDD 项目中限界上下文、聚合根、实体、值对象等概念需要清晰的代码体现。Corellis 可以帮助快速搭建 DDD 项目的骨架。声明文件可以定义聚合根、其包含的实体和值对象、仓库接口、领域服务等。模板库则对应生成聚合根类包含业务 invariants 校验方法。实体和值对象类通常是不可变的。仓库接口UserRepository。领域事件类UserRegisteredEvent。应用服务层协调领域对象和基础设施的薄层。通过这种方式可以确保团队在代码结构上严格遵循 DDD 模式加速复杂业务系统的初期搭建。7. 总结与个人体会使用 Corellis 这类代码生成工具近一年它已经从我们项目中的一个“实验性”工具变成了不可或缺的“基础设施”。最大的感受是它改变的不仅仅是开发速度更是团队协作的心智模型。以前我们花大量时间争论和统一代码风格审查那些千篇一律的 CRUD 代码。现在我们将这些讨论前移聚焦于如何设计出更好的声明格式和模板。一旦模板确定并经过评审生成的代码就是绝对一致的。Code Review 的重点可以放在真正的业务逻辑和创新点上。另一个深刻的体会是“DRY”Don‘t Repeat Yourself原则在元层面的应用。我们不仅在应用代码中避免重复更在“生成代码的规则”中避免重复。维护一套精心设计的模板比维护散落在几十个文件中的相似代码要容易得多。当然引入任何新工具都有成本。Corellis 要求团队前期投入时间学习其概念、设计声明格式、编写和调试模板。这个过程可能会遇到阻力尤其是当生成的代码不完美或与现有工具链集成不畅时。我的建议是从小处着手从痛点开始。不要试图一次性生成整个项目。先找一个重复性最高、最让人头疼的代码片段比如数据库实体类的字段映射用 Corellis 解决它。让大家看到实效再逐步推广到其他领域。最后记住 Corellis 是“助手”而非“主角”。它负责处理那些确定性的、模式化的部分而将创造性的、复杂的业务逻辑留给你。不要试图用它生成一切那样你会陷入编写“生成模板的模板”的无限递归中。找到那个平衡点让它成为你提升工程效率和代码质量的一件利器。

相关新闻