D

DDD 合规性检查

作者:鹿Sir法律合规v1

检查使用 com.alibaba.fa.framework.ddd 基类的 Java 代码是否符合 DDD 分层规范。支持增量检查和全量审计模式。当用户提到 DDD 检查、架构审查、分层合规、代码审查时触发。触发词:DDD检查、架构审查、分层合规、DDD合规。

下载量
270
点赞
68
价格
免费

技能文档

---
name: ddd-check
title: DDD 合规性检查
category: 开发工具
description: "检查使用 com.alibaba.fa.framework.ddd 基类的 Java 代码是否符合 DDD 分层规范。支持增量检查和全量审计模式。当用户提到 DDD 检查、架构审查、分层合规、代码审查时触发。触发词:DDD检查、架构审查、分层合规、DDD合规。"
---

# DDD 合规性检查

检查 Java 代码是否符合 DDD 分层规则。根据参数选择两种模式:

- **`/ddd-check`** — 增量模式,仅检查变更文件(默认)
- **`/ddd-check full`** — 全量模式,检查项目中所有 Java 文件
- **`/ddd-check main`** — 增量模式,对比指定分支
- **`/ddd-check full src/`** — 全量模式,限定目录范围

## 当前状态

在执行步骤 1 之前,先运行以下命令获取当前状态:

```bash
git branch --show-current
git diff HEAD --name-only --diff-filter=ACMR 2>/dev/null | grep '\.java$' || echo '(none)'
find . -name "*.java" -not -path "*/target/*" -not -path "*/test/*" 2>/dev/null | wc -l
```

## 参考资料

所有路径相对于本 SKILL.md 文件。按提示时机读取对应文件:

**规则文件 — 检查对应分层时读取:**
- `references/domain-layer.md` — 检查 `**/domain/**` 文件时读取
- `references/application-layer.md` — 检查 `**/application/**` 文件时读取
- `references/adaptor-layer.md` — 检查 `**/adaptor/**` 文件时读取
- `references/infrastructure-layer.md` — 检查 `**/infrastructure/**` 文件时读取
- `references/client-layer.md` — 检查 `**/client/**` 文件时读取
- `references/model-layer.md` — 检查 `**/model/**` 文件时读取
- `references/anti-patterns.md` — 始终读取(所有模式)

**教学文档 — 用户需要上下文或入门引导时读取:**
- `references/base-classes-reference.md` — 不确定基类契约或异常策略时读取
- `references/overview.md` — 用户问"这个 DDD 框架是什么"或需要了解全貌时读取
- `references/anemic-vs-ddd.md` — 解释某种模式为何错误,或用户问"为什么不能直接用 getter/setter 的 service"时读取
- `references/quick-start-tutorial.md` — 用户想从头构建一个 DDD 功能时读取

## 辅助脚本

以下脚本可用于快速预提交或 CI 门禁检查 — 通过 grep/静态分析覆盖部分规则,无需完整技能工作流:

- `scripts/check-layer-deps.sh [project-root]` — 检测禁止的跨层导入。在提交前或 CI 中运行,提前捕获依赖违规。
- `scripts/check-identity.sh [project-root]` — 验证身份处理:聚合/实体上的 `setId()` 必须仅限于 `infrastructure` 层(插入后回填数据库生成的 id),不得从 `application`/`adaptor` 层调用。在涉及聚合或 Repository 代码时运行。
- `scripts/check-naming.sh [project-root]` — 验证 DDD 命名规范(后缀、前缀)。创建新领域类后运行。

## 技能工作流

### 步骤 1 — 确定模式并收集文件

解析用户调用技能时传入的参数(例如 `/ddd-check full src/`)以确定模式 — 提前分类可避免读取不需要检查的文件:
- 第一个参数为 `full` → **全量模式**。如有第二个参数,则限定到该目录。
- 第一个参数为其他值 → **增量模式**,将其视为基准分支引用。
- 无参数 → **增量模式**,使用默认基准。

**增量模式 — 收集变更文件:**

提供基准分支时:
```bash
git diff <base-branch>...HEAD --name-only --diff-filter=ACMR | grep '\.java$'
```

未提供基准时,默认检查未提交变更:
```bash
git diff HEAD --name-only --diff-filter=ACMR | grep '\.java$'
```

当未提交差异为空时,回退到与 main 分支的差异 — 覆盖已提交完毕但尚未审查的常见场景:
```bash
git diff main...HEAD --name-only --diff-filter=ACMR | grep '\.java$'
```

无 Java 文件变更 → 报告"没有需要检查的变更 Java 文件。"并停止。

**全量模式 — 收集所有文件**(如指定目录则使用指定目录,否则使用 `.`):
```bash
find <dir> -name "*.java" -not -path "*/target/*" -not -path "*/test/*" | sort
```

未找到 Java 文件 → 报告"未找到 Java 源文件。"并停止。

### 步骤 2 — 按分层分类每个文件

先分类可让检查器仅加载相关规则文件,保持上下文聚焦:

| 包路径模式 | 分层 | 规则文件 |
|---|---|---|
| `**/domain/**` | 领域层 | `references/domain-layer.md` |
| `**/application/**` | 应用层 | `references/application-layer.md` |
| `**/adaptor/**` | 适配层 | `references/adaptor-layer.md` |
| `**/infrastructure/**` | 基础设施层 | `references/infrastructure-layer.md` |
| `**/client/**` | 客户端层 | `references/client-layer.md` |
| `**/model/**` | 模型层 | `references/model-layer.md` |

不匹配任何模式的文件(仅全量模式)→ 标记为"未分类"。

### 步骤 2.5 — 按操作模式分类应用层服务

应用层规则因操作模式(写 vs 读 vs 计算)而异 — 同一操作(如直接调用 Repository)在某种模式下是违规,在另一种模式下是正确的。在检查前,根据以下静态信号对每个 `**/application/**` 服务类进行分类:

| 信号 | 模式 | `application-layer.md` 中的规则部分 |
|---|---|---|
| 继承 `ApplicationCmdService` | **命令(写)模式** | B 部分 |
| 继承 `ApplicationQueryService`,类名以聚合名开头(`{Aggregate}QueryAppService`) | **查询(读)模式** | C 部分 |
| 继承 `ApplicationQueryService`,类名以动词开头(`{Verb}QueryAppService`) | **计算模式** | D/E 部分 |

当信号冲突时(如继承 `ApplicationCmdService` 但类名含 `Query`),标记不匹配本身,并按基接口隐含的模式进行检查 — 接口是框架契约,类名是约定。

### 步骤 3 — 读取规则文件

按需懒加载规则,避免增量检查时上下文膨胀:

- **增量模式:** 仅加载匹配到的分层对应的规则文件。始终加载 `references/anti-patterns.md`。
- **全量模式:** 加载所有规则文件。

### 步骤 4 — 逐文件检查

逐文件验证,以便报告违规时附带精确位置和修复方案:

**大型项目策略(全量模式,>30 个文件):** 逐层处理以避免上下文溢出。处理顺序:领域层 → 应用层 → 基础设施层 → 适配层 → 客户端层 → 模型层 → 未分类。

对每个文件,验证以下方面:
1. **结构性** — 正确的基类、正确的包、正确的命名。
2. **依赖性** — 无禁止的跨层导入。
3. **反模式** — 交叉检查反模式规则。
4. **身份标识** — `BaseEntity.isAppended()`(`id == null`)是插入/更新判别器;`setId()` 是公开方法但仅基础设施层可调用(用于插入后回填数据库生成的 id)— 标记 `application`/`adaptor` 层对聚合/实体调用 `setId()` 的情况。
5. **事件** — 领域事件仅在聚合或 Repository 中发布,不得在应用层/适配层发布。
6. **组合** — 聚合根属性必须是 Entity 或 Value 类型;禁止使用基本类型(String、Long 等)作为聚合直接属性。
7. **操作模式**(仅应用层)— 按步骤 2.5 确定的模式匹配对应规则部分进行检查,并标记模式不匹配:查询/计算服务中的写操作调用、仅执行读操作的 Cmd 服务、以聚合命名的计算类(参见 key-checks-by-layer.md 应用层部分)。

增量模式:不检查未变更文件。

### 步骤 5 — 跨文件分析(仅全量模式)

逐文件检查完成后,跨文件分析可捕获单文件层面不可见的违规(缺失实现、循环依赖、命名漂移):

1. **Repository 覆盖率:** 领域层中每个 `{Business}Repository` 接口在基础设施层有对应的 `{Business}RepositoryImpl`。
2. **Converter 覆盖率:** 每个有 RepositoryImpl 的聚合都有对应的 Converter。
3. **依赖方向:** 无循环依赖;依赖向内流动(适配层 → 应用层 → 领域层 ← 基础设施层)。
4. **命名一致性:** DomainService 前缀与 Repository 前缀与 RepositoryImpl 前缀与 Converter 前缀一致。
5. **模型隔离:** 客户端层无模型层导入。

### 步骤 6 — 生成报告

在输出报告前,对每条发现进行自检;修正或删除不符合以下标准的发现,然后重新检查:

1. 引用了具体规则文件章节(如 `domain-layer.md §A.3`)— 不允许无引用的发现。
2. 给出了具体修复方案,而非仅描述问题。
3. 不与注意事项部分矛盾(如标记读模式 Repository 访问或 ResultDO 使用)。
4. 严重程度与严重程度表标准一致。

**增量模式报告格式:**
```
## DDD 检查(增量模式):{branch} → {n} 个文件(基准:{base-ref})

### {FilePath}.java — {分层}
🔴 严重:{问题}。修复方案:{修复}。(参考:{rule-file} §{section})
🟡 高:{问题}。修复方案:{修复}。(参考:{rule-file} §{section})

### 汇总
- 检查了 {n} 个文件
- {x} 个违规(严重:{a},高:{b},中:{c},低:{d})
```

**全量模式报告格式:**
```
## DDD 检查(全量模式):{project} → {n} 个文件

### 领域层 — {count} 个文件
#### {FilePath}.java
🔴 严重:{问题}。修复方案:{修复}。(参考:{rule-file} §{section})

### 跨层发现
🔴 严重:{发现}

### 汇总
- 检查了 {n} 个文件,跨越 {m} 个分层
- {x} 个违规(严重:{a},高:{b},中:{c},低:{d})
- 跨文件问题:{count} 个
```

仅报告实际问题 — 不列出通过检查的文件。零违规 → "所有 {n} 个文件通过 DDD 检查。"

## 严重程度

| 等级 | 标准 | 定级原因 |
|---|---|---|
| **严重** | 架构违规 — 错误的层依赖、领域层依赖基础设施层、缺少必需基类、Repository 缺少 Impl、循环依赖。 | 破坏 DDD 依赖倒置原则;如不在合并前修复将导致级联故障。 |
| **高** | 规则违规 — 错误命名、错误异常模式、领域层中使用任何设计模式、`setId()` 在基础设施层外调用、命名不一致。 | 可编译运行但会悄悄破坏领域隔离;随着更多代码依赖错误模式,修复成本将急剧上升。 |
| **中** | 约定偏差 — 贫血实体、缺少 Field 包装、模型层被客户端层引用、缺少 Converter。 | 当前可运行但阻碍未来能力(脏跟踪、模型演进);修复风险低且可机械化完成。 |
| **低** | 风格 — 缺少 `@Override`。 | 无运行时影响;仅提升可读性。 |

## 各层关键检查

参见 [`references/key-checks-by-layer.md`](references/key-checks-by-layer.md) — 在步骤 4 中与各层规则文件一同读取,作为快速参考检查清单。

## 示例报告

- [增量模式含违规](examples/reports/incremental-report.md)
- [增量模式通过](examples/reports/clean-report.md)
- [全量模式含违规](examples/reports/full-report.md)
- [全量模式通过](examples/reports/full-clean-report.md)

## 注意事项

以下反直觉事实会导致错误判断 — 在标记任何违规前务必阅读:

- `BaseAggregate` 本身**没有 id 字段** — 身份标识位于根 Entity(公开的 `getId()`/`setId()`)。不要因"缺少 id"标记聚合。
- 查询(读模式)服务直接调用 Repository 是**正确**模式 — 仅命令模式需通过 DomainService。不要标记。
- 应用层流程控制(检查适配层结果、提前返回错误码)是场景编排,**不是**禁止的业务逻辑。业务逻辑 = 聚合状态转换、计算公式、规则匹配。
- **两种**异常处理方式均合规:抛出受检异常 `BizException`(默认)或返回 `ResultDO`(按需)。不要将 ResultDO 使用标记为违规。
- 框架 DTO 基类是 `BaseDto`,**不是** `BaseDTO` — Java 区分大小写;精确检查 `extends` 子句。
- `FieldSet.removeAll()` 和 `FieldList.addAll(index, c)` 是**已知的框架源码 bug** — 用户代码规避它们(逐元素删除、尾部追加)是变通方案,不是违规。
- `@Passthrough` 双向生效:字段无方法引用且缺少注解 → 标记;字段**有**注解但被引用 → 同样标记(与自身声明矛盾)。

## 重要提示

- 标记违规时引用具体规则章节(如"domain-layer.md §A.3")。
- 给出具体修复方案,而非仅描述问题。
- 增量模式:不检查未变更文件。
- 全量大型项目:逐层处理以避免上下文溢出。

使用说明

# DDD 合规性检查

检查使用 `com.alibaba.fa.framework.ddd` 基类的 Java 项目是否符合 DDD 分层规范。支持增量检查(默认)和全量审计两种模式。

## 使用方式

```
/ddd-check              # 检查变更的 Java 文件(预提交,快速)
/ddd-check main         # 检查相对于 main 分支的变更
/ddd-check full         # 审计整个项目
/ddd-check full src/    # 审计指定目录
```

## 文件结构

```
.
├── SKILL.md                 # 技能主文件
├── references/              # 规则文件 + 教学文档(12 个)
├── examples/                # 示例代码与报告
│   ├── order-service/       # 合规示例项目(6 层)
│   └── reports/             # 示例检查报告
└── scripts/                 # 快速验证脚本(基于 grep)
    ├── check-layer-deps.sh  # 跨层导入检测
    ├── check-naming.sh      # 命名规范检测
    └── check-identity.sh    # 身份标识违规检测
```

## 检查内容

- 分层隔离 — 禁止错误的跨层导入
- 基类使用 — 聚合 / 实体 / 值对象 / DTO
- 命名规范与跨层命名一致性
- 依赖方向 — 领域层 → 基础设施层为关键检查
- 身份标识 Model B — 业务 id 构造时设定一次
- 领域事件位置 — 仅在聚合/Repository 中发布
- 模型隔离 — 客户端层不得依赖模型层
- 反模式 — 贫血模型、领域层设计模式、异常模式错误

全量模式额外检查:Repository↔Impl 覆盖率、Converter 覆盖率、依赖图、命名一致性。

## 辅助脚本
独立 Shell 脚本,用于快速确定性检查(无需 LLM):
```bash
scripts/check-layer-deps.sh ./src    # 禁止的跨层导入
scripts/check-naming.sh ./src        # 命名规范(后缀检查)
scripts/check-identity.sh ./src      # 身份标识违规
```
每个脚本接受项目根路径参数(默认 `.`),输出 `文件:行号` 格式,退出码 0 通过 / 1 失败。

如何安装此技能?

访问技能市场,点击「安装」按钮,按提示将技能包放入 AI 编程助手的 skills 目录即可。

浏览技能市场

支持平台:Qoder · QoderWork · Claude · Codex 等 AI 编程助手