光船通用代码生成器插件源码全开放:动手拆解动词算子式定制

2026-06-01 27 预计阅读时间:1 分钟
来源:oschina.net AI 摘要 原文链接

免责声明:本文为 AI 摘要整理,建议结合原文阅读。摘要可能省略上下文、版本差异或边界条件,不作为官方说明。

预计阅读时间:9 分钟

动词算子式通用代码生成器"光船"(Lightboat)近日将全部插件源码公开到 Gitee,包括蛋糕商城插件 CookieShopPlugin 和扩展工具插件 ExtendedUtilPlugin。对于一直在用光船做项目生成、却对"客户化动词"只停留在配置层面的开发者来说,这次开放等于拿到了完整的内部图纸——从动词定义、模板渲染到最终产物拼装,每一环都可以直接阅读和改造。

动词算子式:不只是"模板填空"

传统代码生成器的思路是"模板 + 变量替换",输出固定结构的文件。光船的动词算子式设计把生成逻辑拆成一个个"动词"(Verb),每个动词对应一类操作——比如 CreateReadUpdateDelete,或者更业务化的 ShopCartCheckout。动词内部再组合"算子"(Operator)来完成具体的代码拼装步骤。

这种拆法的好处是:新增业务场景时,你不需要重写整块模板,只需要定义一个新动词,或者给已有动词挂一个新算子。插件就是承载这些自定义动词和算子的容器。

两个插件源码:从商城到工具链

CookieShopPlugin——蛋糕商城的全套动词

CookieShopPlugin 是一个完整的电商场景插件,覆盖了从商品展示到下单结算的常见动词。阅读它的源码,你能看到:

  • 动词注册机制:每个动词如何声明自己的名称、入参结构和输出目标。
  • 算子编排顺序:一个动词内部多个算子的执行链是怎么串联的,哪些算子负责生成 DAO,哪些负责生成 Controller。
  • 模板与占位符约定:光船模板文件里 {{fieldName}}{{verbName}} 这类占位符的实际用法,以及模板文件在插件中的存放路径约定。

ExtendedUtilPlugin——通用工具算子扩展

ExtendedUtilPlugin 则偏底层,提供的是跨场景复用的工具类算子,比如:

  • 通用校验算子(字段非空、格式正则)
  • 通用转换算子(日期格式化、枚举映射)
  • 输出目录清理与合并算子

这类插件的价值在于:当你写自己的业务插件时,可以直接引用 ExtendedUtilPlugin 里的算子,不用从零实现基础逻辑。

实践:克隆源码并跑一个最小定制动词

下面用一个可复制的流程,把两个插件源码拉到本地,阅读结构,然后基于 ExtendedUtilPlugin 写一个最小自定义动词。

第一步:克隆插件仓库

# 克隆蛋糕商城插件
git clone https://gitee.com/jerryshensjf/CookieShopPlugin.git

# 克隆扩展工具插件
git clone https://gitee.com/jerryshensjf/ExtendedUtilPlugin.git

# 查看插件目录结构
tree CookieShopPlugin -L 2
tree ExtendedUtilPlugin -L 2

克隆完成后,重点关注每个插件根目录下的 verb 子目录——那里是动词定义的核心文件。算子文件通常在 operator 子目录中,模板在 template 子目录中。

第二步:阅读一个现有动词的定义

打开 CookieShopPlugin 里的任意一个动词定义文件(假设路径为 verb/CreateOrderVerb.json),你会看到类似这样的结构:

{
  "verbName": "CreateOrder",
  "description": "生成订单创建接口及数据访问层",
  "inputFields": [
    { "name": "orderId", "type": "String", "required": true },
    { "name": "customerName", "type": "String", "required": true },
    { "name": "totalAmount", "type": "Decimal", "required": false }
  ],
  "operators": [
    "ValidateRequiredOperator",
    "GenerateDAOOperator",
    "GenerateControllerOperator",
    "MergeOutputOperator"
  ],
  "outputTarget": {
    "language": "java",
    "framework": "springboot",
    "basePath": "{{projectName}}/src/main/java"
  }
}

关键字段一目了然:verbName 是动词标识,operators 列出算子执行链,outputTarget 声明输出语言和路径模板。

第三步:写一个最小自定义动词

基于 ExtendedUtilPlugin 的算子,定义一个只做字段校验和 Markdown 文档生成的轻量动词。在 ExtendedUtilPlugin 的 verb 目录下新建 DescribeFeatureVerb.json

{
  "verbName": "DescribeFeature",
  "description": "根据输入字段列表生成功能描述 Markdown 文档",
  "inputFields": [
    { "name": "featureTitle", "type": "String", "required": true },
    { "name": "fieldList", "type": "List<FieldDef>", "required": true }
  ],
  "operators": [
    "ValidateRequiredOperator",
    "GenerateMarkdownOperator"
  ],
  "outputTarget": {
    "language": "markdown",
    "framework": "none",
    "basePath": "{{projectName}}/docs"
  }
}

然后在 template 目录下新建对应的模板文件 DescribeFeature.md.tpl

# {{featureTitle}}

## 字段说明

| 字段名 | 类型 | 必填 |
|--------|------|------|
{{#each fieldList}}
| {{this.name}} | {{this.type}} | {{#if this.required}}是{{else}}否{{/if}} |
{{/each}}

这个动词只调用了两个算子:ValidateRequiredOperator(来自 ExtendedUtilPlugin,校验 featureTitlefieldList 不为空)和 GenerateMarkdownOperator(渲染上面的模板)。改动量极小,但完整展示了"定义动词 → 选算子 → 写模板"的定制链路。

第四步:在光船中注册并运行

假设光船的主程序已经安装,在光船的插件配置文件(通常是 plugins.jsonlightboat.yaml)中追加本地插件路径:

plugins:
  - path: ./ExtendedUtilPlugin
    enabled: true
  - path: ./CookieShopPlugin
    enabled: true

然后执行生成命令:

# 运行自定义动词
lightboat run --verb DescribeFeature \
  --input '{"featureTitle":"用户注册","fieldList":[{"name":"username","type":"String","required":true},{"name":"email","type":"String","required":true},{"name":"age","type":"Int","required":false}]}' \
  --project my-app

输出会在 my-app/docs/ 下生成一份 用户注册.md,内容就是上面模板渲染的结果。

拿到源码之后该做什么

源码开放的最大价值不是"能跑了",而是"能改了"。几个建议方向:

  • 先读再改:把 CookieShopPlugin 的一个完整动词从定义到模板到算子串联读一遍,理解全链路后再动手定制。
  • 复用算子优先:业务动词尽量引用 ExtendedUtilPlugin 中已有的校验、转换、合并算子,减少重复实现。
  • 小动词验证:新插件先写一个只含 1-2 个算子的最小动词,确认注册和渲染链路通畅后再逐步丰富。
  • 注意输出路径冲突:多个动词如果 basePath 模板相同,合并算子会覆盖文件,务必在动词定义中区分路径或使用文件名模板变量。

光船的动词算子式架构把"生成什么"和"怎么生成"解耦到了动词和算子两个层级。插件源码的开放让这两层都变得透明可改——从阅读 CookieShopPlugin 的电商动词开始,到用 ExtendedUtilPlugin 的算子拼出自己的最小动词,整个链路都可以在本地完成。如果你正在做项目脚手架或内部代码生成工具,这套插件结构值得直接参考和移植。


相关推荐