Agent skill

Xfg Ddd Skills

by fuzhengwei in fuzhengwei/xfg-ddd-skills

DDD 六边形架构设计与部署技能包。提供 Domain/Case/Infrastructure 层设计模式与代码模板,以及 Docker 环境部署脚本。当用户询问 DDD 架构、设计模式或需要部署项目时调用。

MITAuto-check passedDevelopment

Install Xfg Ddd Skills

skills CLI
$ npx skills add fuzhengwei/xfg-ddd-skills --skill xfg-ddd-skills -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install fuzhengwei/xfg-ddd-skills xfg-ddd-skills --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
xfg-ddd-skills
GitHub stars
101
Token cost
~13k tokens
SKILL.md length
1,124 words
Files
23 (incl. scripts, references)
Skills in repo
1
Repo updated
First seen
Licence
MIT

At a glance

DDD 六边形架构设计与部署技能包。提供 Domain/Case/Infrastructure 层设计模式与代码模板,以及 Docker 环境部署脚本。当用户询问 DDD 架构、设计模式或需要部署项目时调用。

  • Works in 8 steps: 确定入口方式(Trigger) → 判断是否需要 Case 层 → Domain 层设计 → …
  • Tasks that involve Domain-driven design
  • SKILL.md covers Scripts, Quick Reference, Architecture Layers and 🚨 Infrastructure 层强制约束(AI 必读), plus 5 more sections
  • Calls docker, docker-compose and mvn; needs MYSQL_ROOT_PASSWORD and HTTP_PASSWORD

What it does

Xfg Ddd Skills is an agent skill from fuzhengwei/xfg-ddd-skills. DDD 六边形架构设计与部署技能包。提供 Domain/Case/Infrastructure 层设计模式与代码模板,以及 Docker 环境部署脚本。当用户询问 DDD 架构、设计模式或需要部署项目时调用。

Its SKILL.md is about 13k tokens, which your agent loads only when the skill is triggered. The skill folder holds 23 other files, including scripts and reference files (for example `README.md`, `references/aggregate.md` and `references/architecture.md`).

It sits in Development, covering Domain-driven design. It works with Docker. The repository describes itself as: ddd skills 一套配合AI工具,完整的 DDD 六边形架构工程搭建与开发解决方案。 @小傅哥. The licence is MIT.

When your agent uses it

  • Tasks that involve Domain-driven design

Example prompts

  • “/xfg-ddd-skills”

Requirements

  • Docker

Workflow steps

8 steps, taken from the step headings in SKILL.md.

  1. 确定入口方式(Trigger)
  2. 判断是否需要 Case 层
  3. Domain 层设计
  4. Infrastructure 层实现
  5. Trigger 层(HTTP Controller)
  6. Case 层(业务编排)
  7. Domain 层(领域服务)
  8. Infrastructure 层(技术实现)

What it can do on your machine

Read from SKILL.md and the folder at commit aca0123. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Ships 1 file in scripts/, which the agent can run.

    Shell commands in SKILL.md call:

    • docker
    • docker-compose
    • mvn
    • curl
    • bash

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    Links to these hosts (documentation or services it may open):

    • github.com

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names these keys or tokens, usually read from environment variables:

    • MYSQL_ROOT_PASSWORD
    • HTTP_PASSWORD
    • MYSQL_PASSWORD
    • RABBITMQ_PASSWORD

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Xfg Ddd Skills loads about 13k tokens when it runs, and up to ~77k if it reads all its reference files. Until then it costs about 30 tokens; SKILL.md has 1,124 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~30
When it runs · the whole SKILL.md, loaded when a task matches
~13k
With references · SKILL.md plus every file in references/, read only if the agent opens them
~77k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); the scripts in this folder are not scanned.

SKILL.md

The full file from fuzhengwei/xfg-ddd-skills at commit aca0123, republished under its MIT licence (© fuzhengwei). 1,124 words, ~13,202 tokens.

Download SKILL.mdSave it as .claude/skills/xfg-ddd-skills/SKILL.md (or your agent's skills folder). This skill also uses 22 other files; get the full folder from GitHub.
name
xfg-ddd-skills
description
DDD 六边形架构设计与部署技能包。提供 Domain/Case/Infrastructure 层设计模式与代码模板,以及 Docker 环境部署脚本。当用户询问 DDD 架构、设计模式或需要部署项目时调用。
version
2.2.4
author
xiaofuge
license
MIT
triggers
DDD, 六边形架构, domain-driven design, 领域驱动设计, ports and adapters, 创建 Entity, 创建聚合根, 创建 DDD 项目, 新建项目, Aggregate, ValueObject, 值对象, 聚合根, 部署, deploy, Docker…

DDD Hexagonal Architecture

Design and implement software using Domain-Driven Design with Hexagonal Architecture. This skill provides patterns, templates, and best practices for building maintainable domain-centric applications.

Scripts

创建 DDD 项目

当用户说"创建 DDD 项目"、"新建项目"、"创建项目"、"创建ddd项目"时,必须使用 scripts/create-ddd-project.sh 脚本。

脚本支持系统: Windows (Git Bash/MSYS2)、Mac (macOS)、Linux,自动检测并适配。

⚠️ 环境提醒: 建议提前安装 JDK 17+ 和 Maven 3.8.*,脚本启动时会自动检测并给出各平台安装指引,未安装也可继续但可能导致生成失败。

⚠️ 重要提醒:必须询问用户项目创建地址

在创建项目前,如果用户没有明确给出工程创建地址,必须询问用户在哪里创建项目。 不能随意创建到默认目录,必须获得用户确认。

示例对话:

用户:帮我创建一个 DDD 项目
AI:好的,我来帮您创建 DDD 项目。请问您希望将项目创建在哪个目录?
     例如:
     1) /Users/xxx/projects
     2) /Users/xxx/Documents
     3) /home/xxx/workspace
     4) 其他路径(请直接输入)

用户:创建在 /Users/xxx/projects 下
AI:确认在 /Users/xxx/projects 下创建项目,开始执行...

流程:

  1. 第一步:确认项目创建目录

    必须询问用户,如果用户未指定,列出可选项供用户选择。

    示例:

    📂 选择项目生成目录
    ──────────────────────────────
    1) /Users/xxx/projects
    2) /Users/xxx/Documents
    3) /home/xxx/workspace
    4) 自定义路径(直接输入路径)
    
    直接回车 = 选择 [1]
  2. 第二步:填写项目配置(逐一询问,直接回车使用默认值)

    参数说明默认值示例
    GroupIdMaven 坐标 groupId,标识组织或公司com.yourcompanycn.bugstack
    ArtifactId项目模块唯一标识名称your-project-nameorder-system
    Version项目版本号1.0.0-SNAPSHOT1.0.0-RELEASE
    PackageJava 代码根包名自动从 GroupId + ArtifactId 推导cn.bugstack.order
    Archetype 版本脚手架模板版本1.8-
  3. 第三步:确认并生成

    显示所有配置,确认后执行 Maven Archetype 生成项目。

脚本执行方式(在 xfg-ddd-skills 项目根目录下运行):

bash
bash scripts/create-ddd-project.sh

⚠️ 必须先 cd 到 xfg-ddd-skills 项目目录下再执行,脚本会自动定位自身路径。 AI 负责引导用户选择目录、填写参数,无需手动拼凑 Maven 命令。 ⚠️ 再次强调:创建项目前必须询问用户项目创建地址,不能随意创建!


Quick Reference

TaskReference
Architecture overviewreferences/architecture.md
Entity designreferences/entity.md
Aggregate designreferences/aggregate.md
Value Object designreferences/value-object.md
Repository patternreferences/repository.md
Port & Adapterreferences/port-adapter.md
Domain Servicereferences/domain-service.md
Case layer orchestrationreferences/case-layer.md
Trigger layerreferences/trigger-layer.md
Infrastructure layerreferences/infrastructure-layer.md
Domain 层设计指南(避免常见错误)references/domain-design-guide.md
Domain 层核心模式references/domain-patterns.md
Infrastructure 层核心模式references/infrastructure-patterns.md
DevOps 部署references/devops-deployment.md
Project structurereferences/project-structure.md
Naming conventionsreferences/naming.md
Docker Imagesreferences/docker-images.md

Architecture Layers

┌─────────────────────────────────────────────────────────────┐
│                     Trigger Layer                            │
│         (HTTP Controller / MQ Listener / Job)               │
└─────────────────────────┬───────────────────────────────────┘
                          ▼
┌─────────────────────────────────────────────────────────────┐
│                       API Layer                              │
│              (DTO / Request / Response)                     │
└─────────────────────────┬───────────────────────────────────┘
                          ▼
┌─────────────────────────────────────────────────────────────┐
│                      Case Layer                              │
│            (Orchestration / Business Flow)                   │
└─────────────────────────┬───────────────────────────────────┘
                          ▼
┌─────────────────────────────────────────────────────────────┐
│                     Domain Layer                             │
│        (Entity / Aggregate / VO / Domain Service)           │
└─────────────────────────┬───────────────────────────────────┘
                          ▲
┌─────────────────────────────────────────────────────────────┐
│                  Infrastructure Layer                        │
│      (Repository Impl / Port Adapter / DAO / PO)            │
└─────────────────────────────────────────────────────────────┘

Dependency Rule: Trigger → API → Case → Domain ← Infrastructure


🚨 Infrastructure 层强制约束(AI 必读)

在生成 Infrastructure 层代码前,AI 必须严格遵守以下结构规范。违反任何一条都是错误的。

✅ 唯一正确的 Infrastructure 层目录结构
{project}-infrastructure/src/main/java/
└── cn/{company}/infrastructure/
    ├── adapter/                        # 适配器实现(实现 Domain 层定义的接口)
    │   ├── port/                       # Port 实现,调用 gateway/
    │   │   └── {Xxx}Port.java
    │   └── repository/                 # Repository 实现,调用 dao/ 和 redis/
    │       └── {Xxx}Repository.java
    ├── dao/                            # MyBatis DAO 接口 + PO 对象
    │   ├── po/                         # PO 对象(数据库映射)
    │   │   └── {Xxx}PO.java
    │   └── I{Xxx}Dao.java             # DAO 接口
    ├── redis/                          # Redis 操作封装
    │   └── IRedisService.java / RedisService.java
    ├── gateway/                        # HTTP/RPC 客户端
    │   ├── dto/                        # 远程调用 DTO
    │   │   ├── {Xxx}RequestDTO.java
    │   │   └── {Xxx}ResponseDTO.java
    │   └── {Xxx}GatewayService.java    # HTTP 服务客户端
    └── config/                         # Spring 配置类(线程池、OkHttp 等)
🚫 严格禁止的错误目录和包名
错误包名错误示例正确位置
persistent/infrastructure.persistent.repository.XxxRepository❌ 禁止! 应放在 adapter/repository/
persistent/repository/infrastructure.persistent.repository.XxxRepository❌ 禁止! 应放在 adapter/repository/
persistent/dao/infrastructure.persistent.dao.IXxxDao❌ 禁止! 应放在 dao/
persistent/po/infrastructure.persistent.po.XxxPO❌ 禁止! 应放在 dao/po/
scenario/infrastructure.scenario.XxxScenario❌ 禁止! DAO 操作只能放在 dao/
config/ 下放 Redis 操作config.RedisConfig.setValue()❌ 禁止! Redis 操作放 redis/
⚠️ 关键规则速记
  1. Repository 实现:只放 adapter/repository/,不放 persistent/、repository/(根目录)
  2. DAO 接口和 PO 对象:只放 dao/ 和 dao/po/,不放 persistent/dao/、persistent/po/
  3. Redis 操作:只放 redis/,不放 config/
  4. Gateway 客户端:只放 gateway/,不放 adapter/gateway/
  5. 永远不要创建 persistent 包 — 这个包名在本架构中不存在
❌ 常见 AI 错误模式
java
// ❌ 错误1:创建 persistent 包放 Repository
infrastructure/persistent/repository/UserRepository.java
// ✅ 正确:infrastructure/adapter/repository/UserRepository.java

// ❌ 错误2:创建 persistent 包放 DAO 和 PO
infrastructure/persistent/dao/IUserDao.java
infrastructure/persistent/dao/po/UserPO.java
// ✅ 正确:infrastructure/dao/IUserDao.java
// ✅ 正确:infrastructure/dao/po/UserPO.java

// ❌ 错误3:在 config 包下写 Redis 操作
infrastructure/config/RedisConfig.java  // 内部包含 setValue() 等操作方法
// ✅ 正确:Redis 操作放 infrastructure/redis/RedisService.java
// ✅ 正确:config/ 只放 Bean 配置(如 RedisTemplate 的序列化配置)

⚠️ Domain 层设计自检清单

在生成 Domain 层代码前,必须逐项检查:

1. 是否有多种处理方式(if-else 判断类型)? → 是:使用策略模式(IXxxStrategy 接口 + 实现类 + Map<String, IXxxStrategy> 注入)

2. 是否有多个独立的校验/过滤步骤(3步以上)? → 是:使用责任链模式(IXxxFilter 接口 + Factory 组装链)

3. Service 方法是否超过 60 行? → 是:拆分为过滤器(校验)+ 策略(执行)+ 私有方法(保存)

4. Infrastructure 层是否包含业务判断逻辑? → 是:将业务校验移到 Domain 层的过滤器中,Infrastructure 只做数据读写

5. 是否跨域直接依赖另一个 Domain 的 Repository? → 是:通过 Case 层编排,或在本域 Repository 接口中聚合所需数据

6. Infrastructure 包名是否正确? → Repository 实现:adapter/repository/(❌ 不是 persistent/repository/) → DAO 操作:dao/(❌ 不是 scenario/dao/、persistent/dao/ 或其他包) → PO 对象:dao/po/(❌ 不是 persistent/po/、persistent/dao/po/ 或其他包) → Redis 操作:redis/(❌ 不是 config/) → ⚠️ 永远不要创建 persistent 包 — 这个包名在本架构中不存在,是严格禁止的

7. Domain 与 Infrastructure 的通信路径是否正确? → 唯一合法路径:Domain 层 → adapter/port/ 或 adapter/repository/(接口定义在 Domain,实现在 Infrastructure) → ❌ Domain 层不允许直接依赖 dao/、redis/、gateway/ 等基础设施包 → ❌ 不允许在 adapter/ 之外新建包做跨层通信

8. Infrastructure 内部调用链是否正确? → adapter/port/ 只能调用 gateway/(HTTP/RPC 客户端) → adapter/repository/ 只能调用 dao/(数据库)、redis/(缓存) → ❌ adapter/port/ 不允许直接调用 dao/ 或 redis/ → ❌ adapter/repository/ 不允许直接调用 gateway/ → ❌ 不允许在 adapter/、dao/、redis/、gateway/、config/ 之外新增基础设施包


⚠️ Domain ↔ Infrastructure 通信铁律

六边形架构的核心约束:Domain 层与 Infrastructure 层之间,只能通过 adapter 适配器进行通信,不允许任何绕行路径。

合法通信路径(✅ 唯一允许)
┌──────────────────────────────────────────────────────────────────┐
│                        Domain 层                                 │
│                                                                  │
│  domain/{domain}/adapter/                                        │
│  ├── port/                                                       │
│  │   └── I{Xxx}Port.java          ← 定义远程调用接口              │
│  └── repository/                                                 │
│      └── I{Xxx}Repository.java    ← 定义数据访问接口              │
│                                                                  │
│  domain/{domain}/service/                                        │
│  └── {Xxx}ServiceImpl.java         ← 业务逻辑只依赖上面的接口     │
└──────────────────────────┬───────────────────────────────────────┘
                           │ 依赖倒置(Domain 定义接口)
                           │
                           ▼
┌──────────────────────────────────────────────────────────────────┐
│                    Infrastructure 层                              │
│                                                                  │
│  infrastructure/adapter/               ← ✅ 唯一合法的通信桥梁     │
│  ├── port/{Xxx}Port.java               实现 IPort,调用 gateway/  │
│  └── repository/{Xxx}Repository.java   实现 IRepository,调用     │
│                                        dao/ 和 redis/            │
│                                                                  │
│  infrastructure/dao/                   ← 被 repository 调用       │
│  infrastructure/redis/                 ← 被 repository 调用       │
│  infrastructure/gateway/               ← 被 port 调用             │
│  infrastructure/config/                ← Spring 配置,不参与通信   │
└──────────────────────────────────────────────────────────────────┘
Infrastructure 内部调用链(✅ 严格遵守)
adapter/port/ ──────调用──────→ gateway/ (HTTP/RPC 客户端)
                                    └── gateway/dto/ (请求/响应DTO)

adapter/repository/ ─调用──→ dao/ (MyBatis DAO + PO)
                    ─调用──→ redis/ (Redis 操作封装)
🚫 严格禁止的违规行为
违规行为说明后果
Domain 直接依赖 dao/Domain Service 直接注入 IXxxDao违反依赖倒置,Domain 耦合 MyBatis
Domain 直接依赖 redis/Domain Service 直接注入 RedisService违反依赖倒置,Domain 耦合 Redis
Domain 直接依赖 gateway/Domain Service 直接注入 XxxGateway违反依赖倒置,Domain 耦合 HTTP
adapter/ 之外新建通信包在 infrastructure/ 下新建 service/、handler/、manager/ 等包做跨层通信破坏六边形架构边界
adapter/port/ 直接调用 dao/Port 实现中直接操作数据库职责混乱,Port 应只负责远程调用
adapter/repository/ 直接调用 gateway/Repository 实现中直接发起 HTTP 请求职责混乱,Repository 应只负责本地数据
任意新增基础设施包在 adapter/、dao/、redis/、gateway/、config/ 之外新增包破坏架构规范,不允许
速记口诀
Domain 定接口,Infra 来实现
通信只过 adapter,port 和 repository
port 对 gateway,repository 对 dao + redis
不绕行、不越权、不乱加包

Domain Layer 目录结构

model/
├── aggregate/              # 聚合对象
│   └── XxxAggregate.java
├── entity/               # 实体对象
│   ├── XxxEntity.java          # 普通实体
│   └── XxxCommandEntity.java  # 命令实体
└── valobj/               # 值对象
    ├── XxxVO.java             # 普通值对象
    └── XxxEnumVO.java         # 枚举值对象

⚠️ 注意:model/ 下没有单独的 command/ 包,命令实体统一放在 entity/ 包下。


🔄 新功能开发完整流程

当用户需要实现一个新功能时,必须按照以下分层调用流程进行开发:

调用链路图
┌─────────────────────────────────────────────────────────────────────────┐
│                           新功能开发流程                                 │
└─────────────────────────────────────────────────────────────────────────┘

  外部请求
      │
      ▼
┌─────────────────────────────────────────────────────────────────────────┐
│ 1. Trigger 层(触发层)                                                  │
│    职责:接收外部请求,路由转发,参数校验,不含业务逻辑                     │
│                                                                         │
│    • HTTP Controller  →  接收 HTTP 请求                                  │
│    • MQ Listener      →  监听消息队列                                    │
│    • Job/Task         →  定时任务/异步任务                               │
│                                                                         │
│    输出:调用 Case 层接口,或轻量场景直接调用 Domain 层                    │
└─────────────────────────┬───────────────────────────────────────────────┘
                          │
                          ▼
┌─────────────────────────────────────────────────────────────────────────┐
│ 2. Case 层(编排层)- 可选,复杂业务需要                                  │
│    职责:跨领域业务编排,流程串联,事务管理                                │
│                                                                         │
│    • 接收 Trigger 调用                                                   │
│    • 编排多个 Domain Service 调用顺序                                     │
│    • 处理跨领域数据转换                                                   │
│    • 管理分布式事务(如需要)                                             │
│                                                                         │
│    输出:调用 Domain 层 Service 接口                                      │
└─────────────────────────┬───────────────────────────────────────────────┘
                          │
                          ▼
┌─────────────────────────────────────────────────────────────────────────┐
│ 3. Domain 层(领域层)                                                   │
│    职责:核心业务逻辑,业务规则校验,领域模型操作                           │
│                                                                         │
│    • Service 服务实现业务逻辑                                             │
│    • Entity/Aggregate 封装业务行为                                       │
│    • 通过 Adapter 接口(Port/Repository)与外部交互                        │
│                                                                         │
│    注意:Domain 层不直接依赖 Infrastructure,只依赖接口                    │
│                                                                         │
│    输出:调用 Adapter 接口(定义在 domain/adapter/ 下)                    │
└─────────────────────────┬───────────────────────────────────────────────┘
                          │ 依赖倒置:Domain 定义接口,Infrastructure 实现
                          ▼
┌─────────────────────────────────────────────────────────────────────────┐
│ 4. Infrastructure 层(基础设施层)                                        │
│    职责:技术实现,数据持久化,外部服务调用                                │
│                                                                         │
│    • adapter/repository/  →  实现 Repository 接口,操作数据库              │
│    • adapter/port/        →  实现 Port 接口,调用外部 HTTP/RPC 服务        │
│    • dao/                 →  MyBatis DAO 接口和 PO 对象                   │
│    • gateway/             →  HTTP/RPC 客户端,远程服务调用                 │
│    • redis/               →  Redis 操作                                  │
│                                                                         │
│    输出:返回数据给 Domain 层,或执行外部调用                              │
└─────────────────────────────────────────────────────────────────────────┘
分层职责速查表
层级职责禁止做的事依赖方向
Trigger接收请求、参数校验、路由转发业务逻辑、直接操作数据库→ API/Case/Domain
Case跨域编排、流程串联、事务管理直接操作数据库、外部 HTTP 调用→ Domain
Domain业务规则、领域模型、逻辑编排直接依赖 MyBatis/Redis/HTTP→ 只依赖接口
Infrastructure数据持久化、外部调用、技术实现业务判断、业务规则实现 Domain 接口
开发流程检查清单

当用户说"帮我实现一个 XXX 功能"时,按以下顺序检查:

Step 1: 确定入口方式(Trigger)

询问用户或根据需求判断:

□ HTTP API 接口?  →  创建 Controller
□ MQ 消息监听?    →  创建 MQ Listener
□ 定时任务?       →  创建 Job
□ 异步任务?       →  创建 Task/Worker
Step 2: 判断是否需要 Case 层
□ 涉及多个领域协作?     →  需要 Case 层
□ 业务流程超过 3 步?    →  需要 Case 层
□ 需要分布式事务?       →  需要 Case 层
□ 单领域、简单业务?     →  Trigger 直接调用 Domain
Step 3: Domain 层设计
□ 定义 Entity/Aggregate/VO
□ 定义 Service 接口和实现
□ 定义 Repository 接口(数据访问)
□ 定义 Port 接口(外部调用,如需要)
Step 4: Infrastructure 层实现
□ 实现 Repository 接口(adapter/repository/)
□ 创建 DAO 接口和 PO 对象(dao/)
□ 实现 Port 接口(adapter/port/,如需要)
□ 创建 Gateway 客户端(gateway/,如需要)
□ 配置 Redis 操作(redis/,如需要)
代码示例:完整调用链

以"订单支付"功能为例,展示完整分层调用:

1. Trigger 层(HTTP Controller)
java
@RestController
@RequestMapping("/api/order")
public class OrderController {
    
    @Resource
    private IOrderPayCase orderPayCase;  // 复杂业务,调用 Case 层
    
    @PostMapping("/pay")
    public Response<OrderPayResponse> pay(@RequestBody OrderPayRequest request) {
        // 1. 参数校验
        if (request.getOrderId() == null || request.getPayAmount() == null) {
            return Response.fail("参数不完整");
        }
        
        // 2. 调用 Case 层(复杂业务)
        // 如果是简单业务,可直接调用 Domain Service
        try {
            OrderPayResult result = orderPayCase.execute(request);
            return Response.success(convertToResponse(result));
        } catch (Exception e) {
            return Response.fail(e.getMessage());
        }
    }
}
2. Case 层(业务编排)
java
public interface IOrderPayCase {
    OrderPayResult execute(OrderPayRequest request) throws Exception;
}

@Service
public class OrderPayCaseImpl implements IOrderPayCase {
    
    @Resource
    private IOrderService orderService;      // 订单领域服务
    @Resource
    private IPaymentService paymentService;  // 支付领域服务
    @Resource
    private IInventoryService inventoryService; // 库存领域服务
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public OrderPayResult execute(OrderPayRequest request) throws Exception {
        log.info("执行订单支付流程,订单号:{}", request.getOrderId());
        
        // 1. 查询订单
        OrderEntity order = orderService.queryOrder(request.getOrderId());
        
        // 2. 扣减库存(调用库存领域服务)
        inventoryService.deduct(order.getProductId(), order.getQuantity());
        
        // 3. 执行支付(调用支付领域服务)
        PaymentResult payment = paymentService.pay(order, request.getPayAmount());
        
        // 4. 更新订单状态(调用订单领域服务)
        orderService.markPaid(order.getOrderId(), payment.getTransactionId());
        
        // 5. 返回结果
        return OrderPayResult.builder()
            .orderId(order.getOrderId())
            .status("PAID")
            .transactionId(payment.getTransactionId())
            .build();
    }
}
3. Domain 层(领域服务)
java
// 订单领域服务接口
public interface IOrderService {
    OrderEntity queryOrder(String orderId);
    void markPaid(String orderId, String transactionId);
}

// 订单领域服务实现
@Service
public class OrderServiceImpl implements IOrderService {
    
    @Resource
    private IOrderRepository orderRepository;  // 依赖 Repository 接口,非实现
    
    @Override
    public OrderEntity queryOrder(String orderId) {
        return orderRepository.queryById(orderId);
    }
    
    @Override
    public void markPaid(String orderId, String transactionId) {
        OrderEntity order = orderRepository.queryById(orderId);
        // 业务规则校验
        if (order.getStatus() != OrderStatus.PENDING_PAY) {
            throw new BusinessException("订单状态不正确,无法支付");
        }
        // 执行业务逻辑
        order.pay(transactionId);  // Entity 封装业务行为
        orderRepository.save(order);
    }
}

// 支付领域服务
public interface IPaymentService {
    PaymentResult pay(OrderEntity order, BigDecimal amount);
}

@Service
public class PaymentServiceImpl implements IPaymentService {
    
    @Resource
    private IPaymentPort paymentPort;  // 依赖 Port 接口,调用外部支付网关
    
    @Override
    public PaymentResult pay(OrderEntity order, BigDecimal amount) {
        // 构建支付请求
        PaymentRequest request = PaymentRequest.builder()
            .orderId(order.getOrderId())
            .amount(amount)
            .build();
        
        // 调用外部支付服务(通过 Port 接口)
        return paymentPort.executePayment(request);
    }
}
4. Infrastructure 层(技术实现)
java
// Repository 实现 - 订单数据访问
@Repository
public class OrderRepositoryImpl implements IOrderRepository {
    
    @Resource
    private IOrderDao orderDao;  // MyBatis DAO
    @Resource
    private StringRedisTemplate redisTemplate;
    
    @Override
    public OrderEntity queryById(String orderId) {
        // 先查缓存
        String cacheKey = "order:" + orderId;
        String cached = redisTemplate.opsForValue().get(cacheKey);
        if (cached != null) {
            return JSON.parseObject(cached, OrderEntity.class);
        }
        
        // 再查数据库
        OrderPO po = orderDao.queryById(orderId);
        OrderEntity entity = convertToEntity(po);
        
        // 写入缓存
        redisTemplate.opsForValue().set(cacheKey, JSON.toJSONString(entity), 30, TimeUnit.MINUTES);
        
        return entity;
    }
    
    @Override
    public void save(OrderEntity entity) {
        OrderPO po = convertToPO(entity);
        orderDao.update(po);
        
        // 更新缓存
        redisTemplate.opsForValue().set("order:" + entity.getOrderId(), 
            JSON.toJSONString(entity), 30, TimeUnit.MINUTES);
    }
}

// Port 实现 - 外部支付网关调用
@Component
public class PaymentPortImpl implements IPaymentPort {
    
    @Resource
    private PaymentGateway paymentGateway;  // HTTP 客户端
    
    @Override
    public PaymentResult executePayment(PaymentRequest request) {
        // 调用外部支付服务
        PaymentGatewayRequest gatewayRequest = convertToGatewayRequest(request);
        PaymentGatewayResponse response = paymentGateway.pay(gatewayRequest);
        
        if (!response.isSuccess()) {
            throw new PaymentException("支付失败:" + response.getErrorMsg());
        }
        
        return PaymentResult.builder()
            .transactionId(response.getTransactionId())
            .status("SUCCESS")
            .build();
    }
}
常见问题与纠正
❌ 错误1:Trigger 层直接调用 Repository
java
// 错误示例
@RestController
public class OrderController {
    @Resource
    private IOrderRepository orderRepository;  // ❌ 直接依赖 Repository
    
    @PostMapping("/order")
    public Response create(@RequestBody OrderRequest request) {
        // 业务逻辑散落在 Controller
        OrderEntity order = new OrderEntity();
        order.setStatus("CREATED");
        orderRepository.save(order);  // ❌ 直接操作数据库
        return Response.success();
    }
}

纠正:Trigger 层只负责接收请求和路由,业务逻辑应下沉到 Domain 层。

❌ 错误2:Domain Service 直接依赖 DAO
java
// 错误示例
@Service
public class OrderServiceImpl implements IOrderService {
    @Resource
    private IOrderDao orderDao;  // ❌ 直接依赖 DAO,违反分层
    
    public OrderEntity queryOrder(String orderId) {
        OrderPO po = orderDao.queryById(orderId);  // ❌ 直接操作数据库
        return convert(po);
    }
}

纠正:Domain 层应依赖 Repository 接口,由 Infrastructure 层实现。

❌ 错误3:Infrastructure 层包含业务逻辑
java
// 错误示例
@Repository
public class OrderRepositoryImpl implements IOrderRepository {
    
    public void save(OrderEntity entity) {
        // ❌ 在 Repository 中做业务判断
        if (entity.getAmount().compareTo(BigDecimal.ZERO) <= 0) {
            throw new BusinessException("金额必须大于0");  // 业务异常不应在这里抛
        }
        orderDao.update(convertToPO(entity));
    }
}

纠正:业务判断应在 Domain 层完成,Infrastructure 层只负责数据读写。

❌ 错误4:跨域直接调用 Repository
java
// 错误示例
@Service
public class OrderServiceImpl implements IOrderService {
    @Resource
    private IInventoryRepository inventoryRepository;  // ❌ 跨域依赖 Repository
    
    public void createOrder(OrderEntity order) {
        // 直接操作库存领域的数据
        InventoryPO inventory = inventoryRepository.queryByProductId(order.getProductId());
        // ...
    }
}

纠正:跨域操作应通过 Case 层编排,或调用目标领域的 Service 接口。

总结口诀
Trigger 只路由,Case 做编排
Domain 管业务,Infra 做实现
接口定义在 Domain,实现放在 Infra 层
依赖永远向内指,Domain 是核心

📦 新功能开发规范

当用户需要增加新功能时,按照以下决策流程进行开发:

决策流程图
用户需要新功能
        │
        ▼
┌───────────────────┐
│ 检查现有领域服务   │ ──是──→ 扩展现有 Service
│ domain/xxx/service│
│ 是否有支持?      │
└─────────┬─────────┘
          │否
          ▼
┌───────────────────┐
│ 创建新的领域?     │ ──是──→ 创建新领域(完整结构)
│ domain/xxx/       │
│                   │
└─────────┬─────────┘
          │
          ▼
┌───────────────────┐
│ Case 层是否需要?  │ ──是──→ 创建 Case 层编排
│ 业务复杂?多领域?  │
└─────────┬─────────┘
          │否(轻量工程)
          ▼
┌───────────────────┐
│ Trigger 直接调用   │ ←── Trigger → Domain
│ Domain 领域层     │
└───────────────────┘
决策指南
问题答案处理方式
现有领域能否支持新功能?✅ 是在现有 Service 中添加方法
是否需要跨多个领域?✅ 是创建 Case 层编排
业务逻辑是否复杂?✅ 是创建 Case 层编排
是否是轻量工程?✅ 是Trigger 直接调用 Domain
Trigger 是否越来越复杂?✅ 是询问用户是否创建 Case 层

场景一:扩展现有领域服务

判断条件:新功能属于现有领域的业务范围。

开发步骤:

  1. 检查现有领域服务

    • 查看 domain/{domain}/service/ 目录
    • 确认是否有相关的 Service 接口
  2. 扩展现有 Service

    • 在现有接口中添加新方法
    • 在实现类中实现新方法

示例:在交易域添加一个"查询订单列表"功能

java
// 1. 在现有接口中添加方法
public interface ITradeRepository {
    // 现有方法...
    
    // 新增:查询订单列表
    List<MarketPayOrderEntity> queryOrderList(QueryOrderRequest request);
}

// 2. 在实现类中实现
@Repository
public class TradeRepository implements ITradeRepository {
    
    @Resource
    private IMcpGatewayDao mcpGatewayDao;
    
    @Override
    public List<MarketPayOrderEntity> queryOrderList(QueryOrderRequest request) {
        // 实现查询逻辑
    }
}

场景二:创建新的领域

判断条件:新功能涉及全新的业务领域,与现有领域无关。

开发步骤:

  1. 创建完整的领域结构

    domain/
    └── {new-domain}/                    # 新领域
        ├── adapter/                    # 适配器接口
        │   ├── port/                  # 端口接口
        │   │   └── I{Xxx}Port.java
        │   └── repository/            # 仓储接口
        │       └── I{Xxx}Repository.java
        ├── model/                     # 领域模型
        │   ├── aggregate/            # 聚合根
        │   ├── entity/               # 实体
        │   └── valobj/               # 值对象
        └── service/                   # 领域服务
            ├── I{Xxx}Service.java     # 服务接口
            └── {能力}/
                └── {Xxx}ServiceImpl.java
  2. 定义 Adapter 接口

    java
    // Repository 接口
    public interface I{Xxx}Repository {
        XxxEntity queryById(Long id);
        void save(XxxEntity entity);
    }
    
    // Port 接口
    public interface I{Xxx}Port {
        void notify(XxxEntity entity) throws Exception;
    }
  3. 定义 Model

    java
    // 实体
    @Data
    public class XxxEntity {
        private Long id;
        private String name;
    }
    
    // 值对象
    @Getter
    public enum XxxStatusEnumVO {
        CREATED("created", "已创建"),
        PROCESSING("processing", "处理中"),
        COMPLETED("completed", "已完成");
        private String code;
        private String info;
    }
  4. 实现 Service

    java
    public interface I{Xxx}Service {
        void process(XxxEntity entity) throws Exception;
    }
    
    @Slf4j
    @Service
    public class XxxServiceImpl implements I{Xxx}Service {
        
        @Resource
        private I{Xxx}Repository repository;
        
        @Resource
        private I{Xxx}Port port;
        
        @Override
        public void process(XxxEntity entity) throws Exception {
            log.info("处理业务:{}", entity.getId());
            // 业务逻辑
            repository.save(entity);
            port.notify(entity);
        }
    }

场景三:创建 Case 层

判断条件:业务涉及多个领域协作,或需要编排多个领域服务。

开发步骤:

  1. 创建 Case 模块结构

    case/
    └── {domain}/
        └── {capability}/
            ├── I{Xxx}Case.java           # Case 接口
            └── impl/
                └── {Xxx}CaseImpl.java    # Case 实现
  2. 定义 Case 接口

    java
    /**
     * XXX 业务编排接口
     * 
     * 职责:编排多个领域服务,完成复杂业务场景
     */
    public interface I{Xxx}Case {
        
        /**
         * 执行 XXX 业务
         */
        void execute(XxxRequest request) throws Exception;
    }
  3. 实现 Case 编排

    java
    /**
     * XXX 业务编排实现
     * 
     * @author xiaofuge
     */
    @Slf4j
    @Service
    public class XxxCaseImpl implements I{Xxx}Case {
        
        @Resource
        private IDomain1Service domain1Service;
        
        @Resource
        private IDomain2Service domain2Service;
        
        @Override
        public void execute(XxxRequest request) throws Exception {
            log.info("执行 XXX 业务");
            
            // 1. 调用领域服务1
            Domain1Result r1 = domain1Service.method1(request.getParam1());
            
            // 2. 调用领域服务2
            domain2Service.method2(r1.getData());
            
            // 3. 组装结果
            // ...
        }
    }

Case 层命名规范:

  • 接口命名:I{Xxx}Case
  • 实现类命名:{Xxx}CaseImpl

Show full SKILL.md (570 more words)Show less
场景四:Trigger 直接调用 Domain

判断条件:轻量工程,业务简单,不需要 Case 层编排。

开发步骤:

  1. 在 Trigger 层直接调用 Domain

    java
    @RestController
    @RequestMapping("/api/xxx")
    public class XxxController {
        
        @Resource
        private I{Xxx}Service xxxService;
        
        @PostMapping("/process")
        public Response<XxxResponse> process(@RequestBody XxxRequest request) {
            try {
                xxxService.process(request.toEntity());
                return Response.success();
            } catch (Exception e) {
                return Response.fail(e.getMessage());
            }
        }
    }
  2. Trigger 层职责

    • 接收请求参数
    • 参数校验
    • 调用 Domain 层
    • 处理异常
    • 返回响应

场景五:Trigger 复杂化后重构为 Case 层

判断条件:Trigger 层代码越来越复杂,包含大量业务逻辑。

警告信号:

  • Controller 代码超过 100 行
  • Controller 中有大量 if-else 判断
  • Controller 依赖多个 Domain Service
  • 业务逻辑难以测试

重构步骤:

  1. 询问用户

    AI:检测到 Trigger 层代码比较复杂,是否需要创建 Case 层来分摊业务逻辑?
        这样可以:
        1. 将业务逻辑从 Controller 移到 Case 层
        2. 提高代码可测试性
        3. 更好的职责分离
  2. 创建 Case 层

    • 按照场景三的方式创建 Case 模块
    • 将 Controller 中的业务逻辑移到 Case 层
  3. 简化 Trigger 层

    java
    // 重构前
    @RestController
    public class XxxController {
        @Resource private IDomain1Service d1;
        @Resource private IDomain2Service d2;
        @Resource private IDomain3Service d3;
        
        public Response process(Request req) {
            // 100+ 行业务逻辑...
        }
    }
    
    // 重构后
    @RestController
    public class XxxController {
        @Resource private I{Xxx}Case xxxCase;
        
        public Response process(Request req) {
            xxxCase.execute(req);
            return Response.success();
        }
    }

完整开发流程示例

需求:在拼团系统中添加"订单超时取消"功能

步骤 1:检查现有领域

trade/
├── adapter/repository/ITradeRepository.java  ← 可以复用
├── model/entity/TradeLockRuleCommandEntity.java
└── service/
    ├── lock/TradeLockOrderService.java     ← 部分相关
    └── refund/TradeRefundOrderService.java  ← 退单逻辑可参考

步骤 2:决策

  • 现有领域(trade)已有相关服务
  • 需要扩展现有 Service
  • 不需要创建新领域

步骤 3:实现

java
// 1. 扩展 ITradeRepository
public interface ITradeRepository {
    // 现有方法...
    
    // 新增:查询超时未支付订单
    List<MarketPayOrderEntity> queryTimeoutUnpaidOrders();
    
    // 新增:取消订单
    void cancelOrder(String orderId);
}

// 2. 扩展 TradeLockOrderService
public interface ITradeLockOrderService {
    // 现有方法...
    
    // 新增:处理超时订单
    void handleTimeoutOrders();
}

@Slf4j
@Service
public class TradeLockOrderService implements ITradeLockOrderService {
    
    @Resource
    private ITradeRepository repository;
    
    @Override
    public void handleTimeoutOrders() {
        log.info("处理超时未支付订单");
        
        // 1. 查询超时订单
        List<MarketPayOrderEntity> orders = repository.queryTimeoutUnpaidOrders();
        
        // 2. 遍历取消
        for (MarketPayOrderEntity order : orders) {
            repository.cancelOrder(order.getOrderId());
        }
    }
}

步骤 4:添加 Trigger

java
@Component
public class OrderTimeoutJob {
    
    @Resource
    private ITradeLockOrderService tradeLockOrderService;
    
    @Scheduled(cron = "0 */5 * * * ?")  // 每5分钟执行
    public void execute() {
        try {
            tradeLockOrderService.handleTimeoutOrders();
        } catch (Exception e) {
            log.error("订单超时处理异常", e);
        }
    }
}

规范速查表
场景判断条件实现位置
扩展现有服务功能属于现有领域domain/{domain}/service/
创建新领域全新业务领域创建完整的 domain/{new}/ 结构
创建 Case 层多领域协作、复杂业务case/{domain}/{capability}/
Trigger 调用轻量工程、简单业务trigger/{domain}/controller/
重构为 CaseTrigger 越来越复杂询问用户后重构

核心原则:

  1. 优先复用:先检查现有领域是否能支持
  2. 单一职责:新功能归到对应领域,不随意扩张
  3. 适度分层:简单场景直接调用,复杂场景创建 Case
  4. 持续演进:Trigger 复杂化时,询问用户是否重构

Quick Templates

Aggregate 聚合对象
java
@Data @Builder @AllArgsConstructor @NoArgsConstructor
public class GroupBuyOrderAggregate {
    /** 用户实体对象 */
    private UserEntity userEntity;
    /** 支付活动实体对象 */
    private PayActivityEntity payActivityEntity;
    /** 支付优惠实体对象 */
    private PayDiscountEntity payDiscountEntity;
    /** 已参与拼团量 */
    private Integer userTakeOrderCount;
}
Entity 普通实体
java
@Data @Builder @AllArgsConstructor @NoArgsConstructor
public class MarketPayOrderEntity {
    private String teamId;
    private String orderId;
    private BigDecimal originalPrice;
    private BigDecimal deductionPrice;
    private BigDecimal payPrice;
    private TradeOrderStatusEnumVO tradeOrderStatusEnumVO;
}
Entity 命令实体(放在 entity 包)
java
/** 命令实体放在 entity 包,使用 CommandEntity 后缀 */
@Data @Builder @AllArgsConstructor @NoArgsConstructor
public class TradeLockRuleCommandEntity {
    private String userId;
    private Long activityId;
    private String teamId;
}
Value Object 值对象
java
@Getter @Builder @AllArgsConstructor @NoArgsConstructor
public class NotifyConfigVO {
    private NotifyTypeEnumVO notifyType;
    private String notifyMQ;
    private String notifyUrl;
}
EnumVO 枚举值对象(可包含策略逻辑)
java
@Getter @AllArgsConstructor
public enum RefundTypeEnumVO {

    UNPAID_UNLOCK("unpaid_unlock", "Unpaid2RefundStrategy", "未支付,未成团") {
        @Override
        public boolean matches(GroupBuyOrderEnumVO groupBuyOrderEnumVO, TradeOrderStatusEnumVO tradeOrderStatusEnumVO) {
            return GroupBuyOrderEnumVO.PROGRESS.equals(groupBuyOrderEnumVO) 
                && TradeOrderStatusEnumVO.CREATE.equals(tradeOrderStatusEnumVO);
        }
    },
    
    PAID_UNFORMED("paid_unformed", "Paid2RefundStrategy", "已支付,未成团") {
        @Override
        public boolean matches(GroupBuyOrderEnumVO groupBuyOrderEnumVO, TradeOrderStatusEnumVO tradeOrderStatusEnumVO) {
            return GroupBuyOrderEnumVO.PROGRESS.equals(groupBuyOrderEnumVO) 
                && TradeOrderStatusEnumVO.COMPLETE.equals(tradeOrderStatusEnumVO);
        }
    };

    private String code;
    private String strategy;
    private String info;

    public abstract boolean matches(GroupBuyOrderEnumVO groupBuyOrderEnumVO, TradeOrderStatusEnumVO tradeOrderStatusEnumVO);

    public static RefundTypeEnumVO getRefundStrategy(GroupBuyOrderEnumVO g, TradeOrderStatusEnumVO t) {
        return Arrays.stream(values()).filter(v -> v.matches(g, t)).findFirst()
                .orElseThrow(() -> new RuntimeException("不支持的退款状态组合"));
    }
}
Domain Service 完整编码
java
/** 1. 定义服务接口 */
public interface ITradeLockOrderService {
    MarketPayOrderEntity lockMarketPayOrder(UserEntity user, PayActivityEntity activity, PayDiscountEntity discount) throws Exception;
}

/** 2. 实现服务(放在子包中) */
@Slf4j @Service
public class TradeLockOrderService implements ITradeLockOrderService {

    @Resource private ITradeRepository repository;
    @Resource private BusinessLinkedList<TradeLockRuleCommandEntity, TradeLockRuleFilterFactory.DynamicContext, TradeLockRuleFilterBackEntity> tradeRuleFilter;

    @Override
    public MarketPayOrderEntity lockMarketPayOrder(UserEntity userEntity, PayActivityEntity payActivityEntity, PayDiscountEntity payDiscountEntity) throws Exception {
        log.info("锁定营销优惠支付订单:{} activityId:{}", userEntity.getUserId(), payActivityEntity.getActivityId());

        // 1. 交易规则过滤(责任链)
        TradeLockRuleFilterBackEntity back = tradeRuleFilter.apply(TradeLockRuleCommandEntity.builder()
                .activityId(payActivityEntity.getActivityId())
                .userId(userEntity.getUserId())
                .teamId(payActivityEntity.getTeamId()).build(),
                new TradeLockRuleFilterFactory.DynamicContext());

        // 2. 构建聚合对象
        GroupBuyOrderAggregate aggregate = GroupBuyOrderAggregate.builder()
                .userEntity(userEntity)
                .payActivityEntity(payActivityEntity)
                .payDiscountEntity(payDiscountEntity)
                .userTakeOrderCount(back.getUserTakeOrderCount())
                .build();

        // 3. 锁定聚合订单
        return repository.lockMarketPayOrder(aggregate);
    }
}
策略模式实现
java
/** 1. 策略接口 */
public interface IRefundOrderStrategy {
    void refundOrder(TradeRefundOrderEntity entity) throws Exception;
    void reverseStock(TeamRefundSuccess success) throws Exception;
}

/** 2. 抽象基类(模板方法) */
@Slf4j
public abstract class AbstractRefundOrderStrategy implements IRefundOrderStrategy {
    @Resource protected ITradeRepository repository;
    @Resource protected ThreadPoolExecutor threadPoolExecutor;

    protected void doReverseStock(TeamRefundSuccess s, String type) throws Exception {
        log.info("退单恢复锁单量 - {}", type);
        repository.refund2AddRecovery(s.getActivityId() + ":" + s.getTeamId(), s.getOrderId());
    }
}

/** 3. 具体策略 */
@Slf4j @Service("paid2RefundStrategy")
public class Paid2RefundStrategy extends AbstractRefundOrderStrategy {
    @Override
    public void refundOrder(TradeRefundOrderEntity e) throws Exception {
        log.info("退单-已支付,未成团 userId:{}", e.getUserId());
        NotifyTaskEntity n = repository.paid2Refund(GroupBuyRefundAggregate.buildPaid2RefundAggregate(e, -1, -1));
        if (n != null) threadPoolExecutor.execute(() -> tradeTaskService.execNotifyJob(n));
    }
    @Override
    public void reverseStock(TeamRefundSuccess s) throws Exception {
        doReverseStock(s, "已支付,但有锁单记录,恢复锁单库存");
    }
}

Core Principles

PrincipleDescription
Dependency InversionDomain defines interfaces, Infrastructure implements
Rich Domain ModelEntity contains both data and behavior
Aggregate BoundaryTransaction consistency inside, eventual consistency outside
Anti-Corruption LayerUse Port to isolate external systems
Lightweight TriggerTrigger layer only routes requests, no business logic

When to Use DDD

Use DDD when:

  • Complex business domain with rich rules
  • Need to capture domain knowledge in code
  • Long-lived project with evolving requirements
  • Team needs shared domain language

Don't use DDD when:

  • Simple CRUD operations
  • Prototype or throwaway code
  • Domain logic is trivial
  • Team unfamiliar with DDD concepts

Example Projects

  • group-buy-market - E-commerce domain
  • ai-mcp-gateway - API gateway domain

🚀 DevOps 部署完整流程

📋 部署检查清单

当用户需要部署 DDD 项目时,按照以下流程执行:

1. 确认项目信息
  • 项目名称(artifactId)
  • 项目路径(代码根目录)
  • 部署环境(开发/测试/生产)
  • 基础依赖(MySQL/Redis/RabbitMQ)
2. 打包构建
bash
cd /path/to/project
mvn clean package -Dmaven.test.skip=true
3. 基础镜像拉取(加速)
bash
# 使用阿里云加速镜像
docker pull registry.cn-hangzhou.aliyuncs.com/xfg-studio/openjdk:17-jdk-slim
docker pull registry.cn-hangzhou.aliyuncs.com/xfg-studio/mysql:8.0.32
docker pull registry.cn-hangzhou.aliyuncs.com/xfg-studio/redis:6.2
4. 数据库部署
bash
cd docs/dev-ops
docker-compose -f docker-compose-environment-aliyun.yml up -d mysql

# 等待 MySQL 就绪后初始化数据库
docker exec -it mysql mysql -uroot -p123456 -e "source /docker-entrypoint-initdb.d/xxx.sql"
5. 应用容器构建
bash
cd ai-mcp-gateway-app
docker build -t system/{artifactId}:1.0.0 .
6. 应用启动
bash
cd docs/dev-ops
docker-compose -f docker-compose-app.yml up -d
7. 验证部署
bash
# 查看容器状态
docker ps -a | grep {artifactId}

# 查看应用日志
docker logs -f {artifactId}

# 健康检查
curl http://localhost:{port}/actuator/health

📁 标准部署目录结构

{project}/
├── docs/
│   └── dev-ops/
│       ├── docker-compose-environment-aliyun.yml  # 基础环境(MySQL/Redis/RabbitMQ)
│       ├── docker-compose-app.yml                  # 应用服务
│       ├── mysql/
│       │   ├── my.cnf                              # MySQL 配置
│       │   └── sql/
│       │       └── {project}.sql                  # 数据库初始化脚本
│       ├── redis/
│       │   └── redis.conf                          # Redis 配置
│       ├── app/
│       │   ├── start.sh                            # 启动脚本
│       │   └── stop.sh                             # 停止脚本
│       └── README.md                               # 部署说明
├── {project}-app/
│   ├── Dockerfile                                   # 应用 Dockerfile
│   ├── pom.xml
│   └── src/main/resources/
│       ├── application.yml
│       ├── application-dev.yml
│       ├── application-test.yml
│       ├── application-prod.yml
│       └── logback-spring.xml

🐳 Dockerfile 标准模板

dockerfile
# 基础镜像
FROM registry.cn-hangzhou.aliyuncs.com/xfg-studio/openjdk:17-jdk-slim

# 作者
MAINTAINER xiaofuge

# 时区配置
ENV TZ=PRC
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

# 添加应用 JAR
ADD target/{artifactId}.jar /{artifactId}.jar

# 暴露端口
EXPOSE {port}

# 启动命令
ENTRYPOINT ["sh","-c","java -jar $JAVA_OPTS /{artifactId}.jar $PARAMS"]

📦 docker-compose-app.yml 标准模板

yaml
version: '3.8'

services:
  {artifactId}:
    image: system/{artifactId}:1.0.0
    container_name: {artifactId}
    restart: on-failure
    ports:
      - "{port}:{port}"
    environment:
      - TZ=PRC
      - SERVER_PORT={port}
      - SPRING_PROFILES_ACTIVE=prod
    volumes:
      - ./logs:/data/log
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"
    networks:
      - my-network
    depends_on:
      - mysql
      - redis

networks:
  my-network:
    driver: bridge

🗄️ docker-compose-environment-aliyun.yml 标准模板

yaml
version: '3.9'

services:
  # MySQL 8.0
  mysql:
    image: registry.cn-hangzhou.aliyuncs.com/xfg-studio/mysql:8.0.32
    container_name: mysql
    command: --default-authentication-plugin=mysql_native_password
    restart: always
    environment:
      TZ: Asia/Shanghai
      MYSQL_ROOT_PASSWORD: 123456
    ports:
      - "13306:3306"
    volumes:
      - ./mysql/my.cnf:/etc/mysql/conf.d/mysql.cnf:ro
      - ./mysql/sql:/docker-entrypoint-initdb.d
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      interval: 5s
      timeout: 10s
      retries: 10
      start_period: 15s
    networks:
      - my-network

  # phpMyAdmin(可选)
  phpmyadmin:
    image: registry.cn-hangzhou.aliyuncs.com/xfg-studio/phpmyadmin:5.2.1
    container_name: phpmyadmin
    ports:
      - "8899:80"
    environment:
      - PMA_HOST=mysql
      - PMA_PORT=3306
      - MYSQL_ROOT_PASSWORD=123456
    depends_on:
      mysql:
        condition: service_healthy
    networks:
      - my-network

  # Redis 6.2
  redis:
    image: registry.cn-hangzhou.aliyuncs.com/xfg-studio/redis:6.2
    container_name: redis
    restart: always
    ports:
      - "16379:6379"
    networks:
      - my-network
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 5s
      retries: 3

  # Redis Commander(可选)
  redis-admin:
    image: registry.cn-hangzhou.aliyuncs.com/xfg-studio/redis-commander:0.8.0
    container_name: redis-admin
    ports:
      - "8081:8081"
    environment:
      - REDIS_HOSTS=local:redis:6379
      - HTTP_USER=admin
      - HTTP_PASSWORD=admin
    depends_on:
      redis:
        condition: service_healthy
    networks:
      - my-network

networks:
  my-network:
    driver: bridge

🚀 快速启动/停止脚本

start.sh
bash
#!/bin/bash

CONTAINER_NAME={artifactId}
IMAGE_NAME=system/{artifactId}:1.0.0
PORT={port}

echo "容器部署开始 ${CONTAINER_NAME}"

# 停止容器
docker stop ${CONTAINER_NAME}

# 删除容器
docker rm ${CONTAINER_NAME}

# 启动容器
docker run --name ${CONTAINER_NAME} \
  --network my-network \
  -p ${PORT}:${PORT} \
  -e SPRING_PROFILES_ACTIVE=prod \
  -v $(pwd)/logs:/data/log \
  -d ${IMAGE_NAME}

echo "容器部署成功 ${CONTAINER_NAME}"

# 查看日志
docker logs -f ${CONTAINER_NAME}
stop.sh
bash
#!/bin/bash

CONTAINER_NAME={artifactId}

echo "停止容器 ${CONTAINER_NAME}"
docker stop ${CONTAINER_NAME}
docker rm ${CONTAINER_NAME}

echo "容器已停止"

🔧 application-prod.yml 标准配置

yaml
server:
  port: {port}

spring:
  application:
    name: {artifactId}
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://${MYSQL_HOST:mysql}:${MYSQL_PORT:3306}/${MYSQL_DATABASE:{database}}?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false
    username: ${MYSQL_USER:root}
    password: ${MYSQL_PASSWORD:123456}
    hikari:
      pool-name: {artifactId}-hikari
      minimum-idle: 10
      maximum-pool-size: 50
      idle-timeout: 300000
      connection-timeout: 30000
      max-lifetime: 1800000
  redis:
    host: ${REDIS_HOST:redis}
    port: ${REDIS_PORT:6379}
  rabbitmq:
    host: ${RABBITMQ_HOST:rabbitmq}
    port: ${RABBITMQ_PORT:5672}
    username: ${RABBITMQ_USER:admin}
    password: ${RABBITMQ_PASSWORD:admin123}

logging:
  level:
    root: INFO
    cn.bugstack: INFO
  file:
    name: /data/log/{artifactId}.log

📊 阿里云镜像加速仓库

所有镜像已同步到阿里云,使用前缀 registry.cn-hangzhou.aliyuncs.com/xfg-studio/

📦 镜像来源:docker-image-pusher 添加新镜像:在 images.txt 添加镜像名,等待1分钟同步

常用镜像速查表
原始镜像阿里云加速地址用途
JDK/Java
openjdk:8-jre-slimregistry.cn-hangzhou.aliyuncs.com/xfg-studio/openjdk:8-jre-slimJava 8 运行环境
openjdk:8-jdkregistry.cn-hangzhou.aliyuncs.com/xfg-studio/openjdk:8-jdkJava 8 开发镜像
openjdk:17-jdk-slimregistry.cn-hangzhou.aliyuncs.com/xfg-studio/openjdk:17-jdk-slimJava 17 运行环境
openjdk:17-ea-17-jdk-slim-busterregistry.cn-hangzhou.aliyuncs.com/xfg-studio/openjdk:17-ea-17-jdk-slim-busterJava 17 EA 版本
数据库
mysql:8.0.32registry.cn-hangzhou.aliyuncs.com/xfg-studio/mysql:8.0.32MySQL 8.0
mysql:8.4.4registry.cn-hangzhou.aliyuncs.com/xfg-studio/mysql:8.4.4MySQL 8.4
postgres:14.18registry.cn-hangzhou.aliyuncs.com/xfg-studio/postgres:14.18PostgreSQL 14
pgvector/pgvector:pg17registry.cn-hangzhou.aliyuncs.com/xfg-studio/pgvector:pg17PostgreSQL 向量库
缓存
redis:6.2registry.cn-hangzhou.aliyuncs.com/xfg-studio/redis:6.2Redis 6.2
redis:7.2registry.cn-hangzhou.aliyuncs.com/xfg-studio/redis:7.2Redis 7.2
redis:7.4.13registry.cn-hangzhou.aliyuncs.com/xfg-studio/redis:7.2/7.4.13Redis 7.4
数据库管理
phpmyadmin:5.2.1registry.cn-hangzhou.aliyuncs.com/xfg-studio/phpmyadmin:5.2.1MySQL Web 管理
redis-commander:0.8.0registry.cn-hangzhou.aliyuncs.com/xfg-studio/redis-commander:0.8.0Redis Web 管理
dpage/pgadmin4:9.1.0registry.cn-hangzhou.aliyuncs.com/xfg-studio/pgadmin4:9.1.0PostgreSQL Web 管理
消息队列
rabbitmq:3.12.9registry.cn-hangzhou.aliyuncs.com/xfg-studio/rabbitmq:3.12.9RabbitMQ
rocketmq:5.1.0registry.cn-hangzhou.aliyuncs.com/xfg-studio/rocketmq:5.1.0RocketMQ
kafka:3.7.0registry.cn-hangzhou.aliyuncs.com/xfg-studio/kafka:3.7.0Kafka
kafka-eagle:3.0.2registry.cn-hangzhou.aliyuncs.com/xfg-studio/kafka-eagle:3.0.2Kafka Eagle
注册中心/配置中心
nacos-server:v2.2.3-slimregistry.cn-hangzhou.aliyuncs.com/xfg-studio/nacos-server:v2.2.3-slimNacos 2.2.3
nacos-server:v3.1.1registry.cn-hangzhou.aliyuncs.com/xfg-studio/nacos-server:v3.1.1Nacos 3.1.1
Web 服务器
nginx:1.25.1registry.cn-hangzhou.aliyuncs.com/xfg-studio/nginx:1.25.1Nginx 1.25
nginx:1.28.0-alpineregistry.cn-hangzhou.aliyuncs.com/xfg-studio/nginx:1.28.0-alpineNginx 1.28 Alpine
任务调度
xxl-job-admin:2.4.0registry.cn-hangzhou.aliyuncs.com/xfg-studio/xxl-job-admin:2.4.0XXL-Job 管理端
xxl-job-aarch64:2.4.0registry.cn-hangzhou.aliyuncs.com/xfg-studio/xxl-job-aarch64:2.4.0XXL-Job ARM 版本
监控
prometheus:2.47.2registry.cn-hangzhou.aliyuncs.com/xfg-studio/prometheus:2.47.2Prometheus
grafana:10.2.0registry.cn-hangzhou.aliyuncs.com/xfg-studio/grafana:10.2.0Grafana
skywalking-oap-server:9.3.0registry.cn-hangzhou.aliyuncs.com/xfg-studio/skywalking-oap-server:9.3.0SkyWalking OAP
skywalking-ui:9.3.0registry.cn-hangzhou.aliyuncs.com/xfg-studio/skywalking-ui:9.3.0SkyWalking UI
搜索引擎
elasticsearch:7.17.14registry.cn-hangzhou.aliyuncs.com/xfg-studio/elasticsearch:7.17.14Elasticsearch
kibana:7.17.14registry.cn-hangzhou.aliyuncs.com/xfg-studio/kibana:7.17.14Kibana
Node
node:18-alpineregistry.cn-hangzhou.aliyuncs.com/xfg-studio/node:18-alpineNode 18
node:20-alpineregistry.cn-hangzhou.aliyuncs.com/xfg-studio/node:20-alpineNode 20
AI/工具
ollama/ollama:0.5.10registry.cn-hangzhou.aliyuncs.com/xfg-studio/ollama:0.5.10Ollama
n8nio/n8n:1.88.0registry.cn-hangzhou.aliyuncs.com/xfg-studio/n8n:1.88.0N8N 工作流
其他
alpine:3.20.1registry.cn-hangzhou.aliyuncs.com/xfg-studio/alpine:3.20.1Alpine Linux
portainer:latestregistry.cn-hangzhou.aliyuncs.com/xfg-studio/portainer:latestDocker 可视化管理
jenkins:2.439registry.cn-hangzhou.aliyuncs.com/xfg-studio/jenkins:2.439Jenkins
sentinel-dashboard:1.8.7registry.cn-hangzhou.aliyuncs.com/xfg-studio/sentinel-dashboard:1.8.7Sentinel 流量控制
canal-server:v1.1.6registry.cn-hangzhou.aliyuncs.com/xfg-studio/canal-server:v1.1.6Canal
zookeeper:3.9.0registry.cn-hangzhou.aliyuncs.com/xfg-studio/zookeeper:3.9.0Zookeeper
拉取镜像示例
bash
# 拉取 MySQL
docker pull registry.cn-hangzhou.aliyuncs.com/xfg-studio/mysql:8.0.32

# 拉取 Redis
docker pull registry.cn-hangzhou.aliyuncs.com/xfg-studio/redis:6.2

# 拉取 Java 17
docker pull registry.cn-hangzhou.aliyuncs.com/xfg-studio/openjdk:17-jdk-slim

⚠️ 常见问题处理

1. MySQL 8.0 认证问题
bash
docker exec mysql mysql -uroot -p123456 -e "ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '123456'; FLUSH PRIVILEGES;"
2. 容器网络不通

确保所有容器在同一个网络:

yaml
networks:
  - my-network
3. 端口冲突

修改 docker-compose.yml 中的端口映射:

yaml
ports:
  - "13306:3306"  # 改为非标准端口
4. 应用无法连接数据库

检查环境变量配置和健康检查依赖:

yaml
depends_on:
  mysql:
    condition: service_healthy

📝 部署操作流程示例

当用户说"帮我部署 ai-mcp-gateway"时,执行:

  1. 确认项目信息

    • 项目路径:/Users/fuzhengwei/Documents/project/ddd-demo/ai-mcp-gateway
    • 端口:8091
    • 镜像:system/ai-mcp-gateway:1.0.0
  2. 执行部署

bash
# 进入项目目录
cd /Users/fuzhengwei/Documents/project/ddd-demo/ai-mcp-gateway

# 打包
mvn clean package -Dmaven.test.skip=true

# 构建 Docker 镜像
cd ai-mcp-gateway-app
docker build -t system/ai-mcp-gateway:1.0.0 .

# 部署基础环境
cd ../docs/dev-ops
docker-compose -f docker-compose-environment-aliyun.yml up -d

# 等待 MySQL 就绪
sleep 30

# 初始化数据库
docker exec -i mysql mysql -uroot -p123456 < mysql/sql/ai_mcp_gateway_v2.sql

# 启动应用
docker-compose -f docker-compose-app.yml up -d

# 验证
docker ps | grep ai-mcp-gateway
curl http://localhost:8091/api/gateway/list
  1. 部署完成检查
    • 容器状态正常
    • 日志无报错
    • 健康检查通过

© fuzhengwei, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

SKILL.md and 22 other files (scripts, references) in the repository root of fuzhengwei/xfg-ddd-skills.

  • SKILL.md
  • .DS_Store
  • .gitignore
  • README.md
  • references/aggregate.md
  • references/architecture.md
  • references/case-layer.md
  • references/devops-deployment.md
  • references/docker-images.md
  • references/domain-design-guide.md
  • references/domain-patterns.md
  • references/domain-service.md
  • references/entity.md
  • references/infrastructure-layer.md
  • references/infrastructure-patterns.md
  • references/naming.md
  • references/port-adapter.md
  • references/project-structure.md
  • references/repository.md
  • references/trigger-layer.md
  • … and 3 more

Open the folder on GitHubat commit aca0123

Compare with similar skills

Xfg Ddd Skills next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Xfg Ddd Skills compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Xfg Ddd Skills this skillfuzhengwei/xfg-ddd-skills101—~13kAutomated safety check: PassMIT
Kratos Developmentaide-family/moon253—~1.5kAutomated safety check: PassNone
Spring Boot Project Creatorgiuseppe-trisciuoglio/developer-kit357—~3.4kAutomated safety check: NotesMIT
Domain Modelingfossasia/eventyay-interpretation1.6k30 repos~821Automated safety check: PassApache-2.0
Megatron-LM Container and Dependency SetupNVIDIA/Megatron-LM18k—~2.6kAutomated safety check: PassApache-2.0
Run Dozzle Dev Instanceamir20/dozzle15k—~747Automated safety check: PassMIT

Similar skills

  • Kratos Development

    aide-family/moon

    Develops Go microservices with Kratos v2 following official design philosophy, DDD/Clean Architecture layout, Protobuf API, error/config/middleware patterns, and observability.

    253 GitHub stars~1.5k tokensUpdated 3 mo ago
    Backend & APIsAuto-check passed
  • Spring Boot Project Creator

    giuseppe-trisciuoglio/developer-kit

    Creates and scaffolds a new Spring Boot project (3.x or 4.x) by downloading from Spring Initializr, generating package structure (DDD or Layered architecture), configuring JPA, SpringDoc OpenAPI…

    357 GitHub stars~3.4k tokensUpdated 1 mo ago
    Backend & APIsAuto-check: notes
  • Domain Modeling

    fossasia/eventyay-interpretation

    Build and sharpen a project's domain model. An agent skill from fossasia/eventyay-interpretation.

    1.6k GitHub starsUsed in 30 repos~821 tokens
    DevelopmentAuto-check passed
  • Official

    Walks an agent through working inside the Megatron-LM CI container and changing dependencies with uv, so lock files resolve the same locally and in CI.

    18k GitHub stars~2.6k tokensUpdated today
    DevelopmentAuto-check passed
  • Starts a Dozzle dev server on a port derived from the current worktree so you can test by hand in a browser, without disturbing instances started elsewhere.

    15k GitHub stars~747 tokensUpdated today
    DevelopmentAuto-check passed
  • Domain Modeling

    brim-borium/spotify_sdk

    Build and sharpen a project's domain model. An agent skill from brim-borium/spotify_sdk.

    166 GitHub starsUsed in 7 repos~806 tokens
    DevelopmentAuto-check passed

Works with

Categories

Questions about Xfg Ddd Skills

What does Xfg Ddd Skills do?

DDD 六边形架构设计与部署技能包。提供 Domain/Case/Infrastructure 层设计模式与代码模板,以及 Docker 环境部署脚本。当用户询问 DDD 架构、设计模式或需要部署项目时调用。. Xfg Ddd Skills is an agent skill from fuzhengwei/xfg-ddd-skills.

When should I use Xfg Ddd Skills?

Xfg Ddd Skills fits situations like: tasks that involve Domain-driven design.

How do I install Xfg Ddd Skills in Claude Code?

Run `npx skills add fuzhengwei/xfg-ddd-skills --skill xfg-ddd-skills -a claude-code`. Or copy the skill folder (the fuzhengwei/xfg-ddd-skills repository) into .claude/skills/xfg-ddd-skills in your project. Claude Code loads it when a task matches its description.

How do I install Xfg Ddd Skills in Codex?

Run `npx skills add fuzhengwei/xfg-ddd-skills --skill xfg-ddd-skills -a codex`. Or copy the skill folder (the fuzhengwei/xfg-ddd-skills repository) into .agents/skills/xfg-ddd-skills in your project. Codex loads it when a task matches its description.

Can I use Xfg Ddd Skills in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add fuzhengwei/xfg-ddd-skills --skill xfg-ddd-skills -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/xfg-ddd-skills, .gemini/skills/xfg-ddd-skills, .github/skills/xfg-ddd-skills and .opencode/skills/xfg-ddd-skills in your project.

What does Xfg Ddd Skills need to run?

Going by SKILL.md and its folder, Xfg Ddd Skills needs the command-line tools its instructions call (docker, docker-compose, mvn, curl and bash) and credentials named MYSQL_ROOT_PASSWORD, HTTP_PASSWORD, MYSQL_PASSWORD and RABBITMQ_PASSWORD. Our summary lists: Docker.

Does Xfg Ddd Skills access the network?

SKILL.md names 1 domain. As links in the text: github.com. This is read from the text; nothing was executed.

Is Xfg Ddd Skills safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. The check reads SKILL.md only: the scripts in the folder are not scanned, so read them before running anything.

What licence does Xfg Ddd Skills use?

Xfg Ddd Skills is published under the MIT licence (declared in SKILL.md). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Xfg Ddd Skills use?

About 13k tokens (SKILL.md is roughly 53k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full. Its references folder adds about 64k tokens, read only when the agent opens those files.

What are the alternatives to Xfg Ddd Skills?

Skills that share tags, products or a category with Xfg Ddd Skills: Kratos Development (aide-family/moon, 253 stars), Spring Boot Project Creator (giuseppe-trisciuoglio/developer-kit, 357 stars), Domain Modeling (fossasia/eventyay-interpretation, 1.6k stars) and Megatron-LM Container and Dependency Setup (NVIDIA/Megatron-LM, 18k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Xfg Ddd Skills?

fuzhengwei (a GitHub user) maintains it in fuzhengwei/xfg-ddd-skills, which has 101 GitHub stars. The repository was last updated on May 2, 2026.

Source: fuzhengwei/xfg-ddd-skills on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.