huiyiruciduojiao d53c2f86a8 Update README.md
2026-01-11 04:34:03 +08:00
2026-01-11 04:31:58 +08:00
2026-01-11 04:34:03 +08:00
2026-01-11 04:32:26 +08:00

DDD 脚手架生成工具

一个功能强大、高度可配置的领域驱动设计DDD项目脚手架生成工具支持模块化单体架构。

核心特性

灵活的架构支持

  • 多上下文管理一次生成多个有界上下文Bounded Context
  • 分层架构:支持 API、Domain、Application、Infrastructure、Interfaces 等标准 DDD 分层
  • 目录结构自定义:支持标准 Maven 结构或自定义扁平结构
  • 模块化命名:灵活的模块命名模式,满足不同团队规范

强大的配置能力

  • 树形目录配置:直观的嵌套结构定义,所见即所得
  • 文件模板系统:在配置中直接定义文件内容和模板
  • 模板变量:完全可配置的变量系统,支持多层引用
  • 占位符选项:自动生成 .keeppackage-info.java、README 等文件

安全的回滚机制

  • 文件哈希验证:基于 SHA256 哈希确保文件未被修改
  • 智能跳过:自动跳过用户修改的文件,不会误删
  • 父目录保护:自动保护包含用户文件的目录结构
  • 清单追踪:完整记录所有生成的文件和目录

其他实用功能

  • Dry-run 模式:预览生成结果,不实际创建文件
  • 覆盖策略skip、overwrite、fail 三种策略可选
  • 详细日志:支持 verbose 模式,方便调试
  • 向后兼容:完全兼容旧版配置格式

快速开始

安装

# 克隆仓库
git clone https://github.com/huiyiruciduojiao/scaffold_ddd.git
cd scaffold_ddd

# 无需额外依赖Python 3.8+ 即可运行
python scaffold_ddd.py --help

初始化配置

# 生成示例配置文件
python scaffold_ddd.py --init-config scaffold.json

# 编辑配置文件
vim scaffold.json

生成项目

# 基本用法
python scaffold_ddd.py --config scaffold.json --contexts auth,user

# 预览模式(不实际创建文件)
python scaffold_ddd.py --config scaffold.json --contexts auth --dry-run

# 详细日志
python scaffold_ddd.py --config scaffold.json --contexts auth -v

回滚

# 预览回滚
python scaffold_ddd.py --rollback modules/auth/manifest.json --dry-run

# 执行回滚
python scaffold_ddd.py --rollback modules/auth/manifest.json

配置文件详解

基本配置

{
  "root": "modules",                    // 上下文根目录
  "package_base": "top.ysit.travel",    // 基础包名
  "contexts": ["auth", "user"],         // 要生成的上下文列表
  "layers": [                           // 要生成的层
    "api",
    "domain", 
    "application",
    "infrastructure",
    "interfaces"
  ],
  "use_standard_structure": false,      // 是否使用标准 Maven 结构
  "overwrite": "skip"                   // 覆盖策略skip | overwrite | fail
}

模块命名配置

{
  "naming": {
    "module_name_pattern": "{layer}",        // 模块名模式
    "context_dir_pattern": "{context}"       // 上下文目录模式
  }
}

示例

  • {layer} → 生成 api/, domain/, application/
  • {context}-{layer} → 生成 auth-api/, auth-domain/

占位符配置

{
  "placeholders": {
    "create_keep_files": true,        // 为空目录创建 .keep 文件
    "create_package_info": true,      // 创建 package-info.java
    "create_layer_readme": false,     // 创建层级 README
    "create_context_readme": false    // 创建上下文 README
  }
}

模板变量配置

{
  "template_vars": {
    "package": "{package_base}.{context}",
    "context_package": "{package_base}.{context}",
    "layer_package": "{package}.{layer}",
    "author": "Your Name",
    "organization": "Your Org"
  }
}

内置变量

  • {context} - 上下文名称(如 auth
  • {layer} - 层名称(如 domain
  • {module} - 模块名称(如 auth-domain
  • {package_base} - 基础包名(如 top.ysit.travel

自定义变量:支持引用其他变量,自动多轮解析

目录结构配置

方式一:树形结构(推荐)

{
  "layer_dirs": {
    "api": {
      "contract": {},
      "event": {},
      "client": {},
      "_files": {
        "package-info.java": "package {layer_package};\n"
      }
    },
    "domain": {
      "model": {
        "aggregate": {
          "_files": {
            ".gitkeep": ""
          }
        },
        "entity": {},
        "vo": {}
      },
      "repository": {},
      "service": {}
    }
  }
}

方式二:列表格式(兼容旧版)

{
  "layer_dirs": {
    "domain": [
      "model/aggregate",
      "model/entity",
      "repository"
    ]
  }
}

使用示例

示例 1: 生成单个上下文

python scaffold_ddd.py \
  --config scaffold.json \
  --contexts auth

生成结构

modules/
  └── auth/
      ├── manifest.json
      ├── api/
      │   ├── package-info.java
      │   ├── contract/
      │   ├── event/
      │   └── client/
      ├── domain/
      │   ├── package-info.java
      │   ├── model/
      │   │   ├── aggregate/
      │   │   ├── entity/
      │   │   └── vo/
      │   ├── repository/
      │   └── service/
      └── ...

示例 2: 生成多个上下文

python scaffold_ddd.py \
  --config scaffold.json \
  --contexts auth,user,order

示例 3: 使用命令行参数覆盖配置

python scaffold_ddd.py \
  --config scaffold.json \
  --contexts auth \
  --package-base com.mycompany.project \
  --overwrite overwrite

示例 4: 预览生成结果

python scaffold_ddd.py \
  --config scaffold.json \
  --contexts auth \
  --dry-run \
  --manifest-stdout

示例 5: 安全回滚

# 1. 先预览回滚效果
python scaffold_ddd.py --rollback modules/auth/manifest.json --dry-run -v

# 2. 确认无误后执行
python scaffold_ddd.py --rollback modules/auth/manifest.json

高级功能

1. 文件模板

在配置中直接定义文件内容:

{
  "layer_dirs": {
    "domain": {
      "exception": {
        "_files": {
          "DomainException.java": "package {context_package}.domain.exception;\n\n/**\n * Base domain exception for {context} context\n * @author {author}\n */\npublic class DomainException extends RuntimeException {\n    public DomainException(String message) {\n        super(message);\n    }\n}\n"
        }
      }
    }
  }
}

2. 从外部文件读取

{
  "_files": {
    "README.md": {
      "content_from": "templates/domain_readme.md"
    }
  }
}

3. 智能回滚

场景 1:所有文件未修改

$ python scaffold_ddd.py --rollback modules/auth/manifest.json
INFO ✓ Verified 34 file(s) by hash
INFO Deleted 35 file(s)
INFO Deleted empty context directory: modules\auth
INFO Rollback completed successfully

场景 2:部分文件被修改

$ python scaffold_ddd.py --rollback modules/auth/manifest.json
WARNING ⚠ Hash verification failed for 2 file(s). These files will be skipped.
WARNING   - modules\auth\api\README.md
INFO Deleted 32 file(s)
INFO Protected 5 path(s) due to skipped files
WARNING ⚠ Rollback completed with 2 file(s) skipped

4. 自定义包结构

标准结构use_standard_structure: true

modules/auth/domain/
  └── src/main/java/
      └── top/ysit/travel/auth/domain/
          ├── model/
          └── repository/

扁平结构use_standard_structure: false

modules/auth/domain/
  ├── model/
  └── repository/

完整配置示例

{
  "root": "modules",
  "package_base": "top.ysit.travel",
  "contexts": ["auth", "user", "order"],
  "layers": ["api", "domain", "application", "infrastructure", "interfaces"],
  "java_source_dir": "src/main/java",
  "resources_dir": "src/main/resources",
  "overwrite": "skip",
  "dry_run": false,
  "emit_manifest": true,
  "manifest_name": "manifest.json",
  "use_standard_structure": false,

  "naming": {
    "module_name_pattern": "{layer}",
    "context_dir_pattern": "{context}"
  },

  "placeholders": {
    "create_keep_files": true,
    "create_package_info": true,
    "create_layer_readme": false,
    "create_context_readme": false
  },

  "template_vars": {
    "package": "{package_base}.{context}",
    "context_package": "{package_base}.{context}",
    "layer_package": "{package}.{layer}",
    "author": "DDD Scaffold Tool",
    "organization": "YSIT",
    "license": "MIT"
  },

  "layer_dirs": {
    "api": {
      "contract": {},
      "event": {},
      "client": {},
      "_files": {
        "package-info.java": "/**\n * API contracts for {context} context.\n * @author {author}\n */\npackage {layer_package};\n"
      }
    },
    
    "domain": {
      "model": {
        "aggregate": {
          "_files": {
            ".gitkeep": ""
          }
        },
        "entity": {},
        "vo": {},
        "enum": {}
      },
      "repository": {},
      "event": {},
      "service": {},
      "exception": {
        "_files": {
          "DomainException.java": "package {context_package}.domain.exception;\n\npublic class DomainException extends RuntimeException {\n    public DomainException(String message) {\n        super(message);\n    }\n}\n"
        }
      }
    },
    
    "application": {
      "command": {},
      "usecase": {},
      "query": {
        "dto": {}
      },
      "assembler": {},
      "port": {
        "in": {},
        "out": {}
      },
      "security": {},
      "handler": {}
    },
    
    "infrastructure": {
      "persistence": {
        "mapper": {},
        "po": {},
        "convert": {},
        "repository": {}
      },
      "event": {},
      "config": {}
    },
    
    "interfaces": {
      "web": {
        "request": {},
        "response": {}
      },
      "facade": {},
      "doc": {}
    }
  }
}

命令行参数

python scaffold_ddd.py [OPTIONS]

Options:
  --config PATH              配置文件路径
  --init-config PATH         生成示例配置文件
  --root DIR                 上下文根目录(覆盖配置)
  --package-base PKG         基础包名(覆盖配置)
  --contexts CONTEXTS        逗号分隔的上下文列表
  --layers LAYERS            逗号分隔的层列表
  --overwrite POLICY         覆盖策略skip | overwrite | fail
  --dry-run                  预览模式,不创建文件
  --no-manifest              不生成 manifest.json
  --manifest-stdout          输出 manifest 到标准输出
  --manifest-write-in-dry-run  在 dry-run 模式也写入 manifest
  --rollback MANIFEST_PATH   使用指定 manifest 回滚
  -v, --verbose              详细日志输出
  --help                     显示帮助信息

常见问题

Q1: 如何选择目录结构?

标准 Maven 结构 (use_standard_structure: true)

  • 适合传统 Maven/Gradle 项目
  • IDE 友好,自动识别源码目录
  • 目录层级较深

扁平结构 (use_standard_structure: false)

  • 目录结构简洁
  • 适合模块化单体架构
  • 需要手动配置 IDE 源码目录

Q2: 回滚会删除我修改的文件吗?

不会! 回滚功能使用 SHA256 哈希验证:

  • 自动跳过被修改的文件
  • 保护包含被修改文件的父目录
  • 详细日志显示被跳过的文件

Q3: 如何处理包名?

使用模板变量灵活控制:

{
  "template_vars": {
    "package": "{package_base}.{context}",
    "layer_package": "{package}.{layer}"
  }
}

在文件模板中引用:

package {layer_package};  // → top.ysit.travel.auth.domain

Q4: 可以只生成部分层吗?

可以!使用 --layers 参数:

python scaffold_ddd.py \
  --config scaffold.json \
  --contexts auth \
  --layers api,domain

Q5: 如何在团队中共享配置?

  1. scaffold.json 提交到版本控制
  2. 团队成员使用相同的配置文件
  3. 根据项目需要在 CI/CD 中自动生成

Q6: 支持哪些编程语言?

虽然默认配置面向 Java但通过自定义配置可以支持任何语言

  • 修改文件扩展名
  • 自定义文件模板
  • 调整目录结构

最佳实践

1. 版本控制策略

# 提交配置文件
git add scaffold.json scaffold_ddd.py
git commit -m "Add DDD scaffold configuration"

# 不要提交生成的代码到主分支
echo "modules/" >> .gitignore

# 或者只提交初始骨架,后续开发不提交
git add modules/auth/domain/model/
git commit -m "Add domain model skeleton"

2. 配置组织

{
  "_comment": {
    "description": "Auth context scaffold configuration",
    "author": "Team Name",
    "last_updated": "2026-01-11"
  },
  
  "template_vars": {
    "_comment": "Package naming conventions",
    "package": "{package_base}.{context}",
    ...
  }
}

3. 渐进式采用

# 步骤 1: 预览效果
python scaffold_ddd.py --config scaffold.json --contexts auth --dry-run

# 步骤 2: 生成一个上下文测试
python scaffold_ddd.py --config scaffold.json --contexts auth

# 步骤 3: 确认无误后生成所有上下文
python scaffold_ddd.py --config scaffold.json

4. 模板复用

将常用文件模板提取到外部:

templates/
  ├── domain_exception.java
  ├── package-info.java
  └── README.md

scaffold.json:
{
  "_files": {
    "DomainException.java": {
      "content_from": "templates/domain_exception.java"
    }
  }
}

贡献指南

欢迎提交 Issue 和 Pull Request

报告问题

提交 Issue 时请包含:

  • Python 版本
  • 完整的配置文件
  • 错误信息和日志
  • 重现步骤

提交代码

  1. Fork 项目
  2. 创建特性分支
  3. 提交变更
  4. 创建 Pull Request

License

MIT License - 详见 LICENSE 文件

Description
No description provided
Readme MIT 50 KiB
Languages
Python 100%