Avro 到 DDD 模型转换注解规范
本文档定义了用于 Avro IDL 到 MdBlueprint DDD 模型转换的注解规范。这些注解用于标记 Avro Schema 中的元素,指导转换器生成相应的 DDD 模型组件。
注解分类
1. 类型级注解(Type-Level Annotations)
用于标记 Protocol 和 Record 的注解。
| 注解名称 | 适用元素 | 领域设计元素 | 属性 |
|---|---|---|---|
| @CompileUnit | Record Protocol | 通用资源 | - module: 模块名称 - domain: 所属领域 - name: 资源名称 - desc: 资源描述 - type: 资源类型(参照AssetType枚举) - template: 模板名称 |
| @BizCapacityApi | Protocol | 业务能力API服务 | - name: API服务名称 - desc: API服务描述 |
| @BizCapacityService | Protocol | 业务能力服务 | - name: 服务名称 - desc: 服务描述 |
| @DomainService | Protocol | 领域服务 | - domain: 所属领域 - name: 服务名称 - desc: 服务描述 |
| @DomainObject | Record | 领域对象 | - domain: 所属领域 - name: 对象名称 - type: 对象类型(参照DomainObjectType枚举) - desc: 对象描述 |
| @Command | Record | 命令 | - domain: 所属领域 - name: 命令名称 - desc: 命令描述 |
| @ApplicationService | Protocol | 应用服务 | - domain: 所属领域 - name: 服务名称 - desc: 服务描述 |
| @Query | Record | 查询 | - domain: 所属领域 - name: 查询名称 - desc: 查询描述 |
| @JobProcessor | Protocol | 定时任务处理器 | - domain: 所属领域 - name: 处理器名称 - desc: 处理器描述 |
| @DomainEventConsumer | Protocol | 领域事件消费者 | - domain: 所属领域 - name: 消费者名称 - desc: 消费者描述 |
| @DomainEvent | Record | 领域事件 | - domain: 所属领域 - name: 事件名称 - desc: 事件描述 |
2. 字段级注解(Field-Level Annotations)
用于标记记录字段的注解。
| 注解名称 | 适用元素 | 领域设计元素 | 适用父级元素 | 属性 |
|---|---|---|---|---|
| @DomainId | Field | 领域标识 | @DomainObject | - name: 标识名称 - desc: 标识描述 |
| @DomainState | Field | 领域状态 | @DomainObject | - name: 状态字段名称 - desc: 状态描述 |
| @DomainField | Field | 领域字段 | @DomainObject | - name: 字段名称(默认为空) - desc: 字段描述(默认为空) - column: 数据库列名(默认为空,使用snake_case转换) - prefix: 列名前缀(默认为空) - nullable: 是否可为空(默认true) - length: 字段长度(默认255) - precision: 数字精度(默认0) - scale: 数字小数位数(默认0) - type: 字段类型(默认为空) - strategy: 持久化策略(默认INHERIT) - template: 模板名称(默认为空) - select: 是否参与查询(默认true) - update: 是否参与更新(默认true) - insert: 是否参与插入(默认true) |
注意:
@DomainField注解仅用于@DomainObject标记的领域对象字段@Command、@Query、@DomainEvent等DTO对象不需要持久化,其字段无需使用@DomainField注解- 大部分情况下无需显式使用@DomainField注解,系统会根据字段名自动应用snake_case命名规范和默认策略
3. 方法级注解(Method-Level Annotations)
用于标记协议消息的注解。
| 注解名称 | 适用元素 | 领域设计元素 | 适用父级元素 | 属性 |
|---|---|---|---|---|
| @DomainMethod | Message | 领域方法 | @DomainService @ApplicationService | - name: 方法名称 - desc: 方法描述 - template: 模板名称 - steps: 执行步骤数组 |
| @CommandHandler | Message | 命令处理器 | @DomainService @ApplicationService | - name: 处理器名称 - desc: 处理器描述 - template: 模板名称 - steps: 执行步骤数组 |
| @QueryHandler | Message | 查询处理器 | @ApplicationService | - name: 处理器名称 - desc: 处理器描述 - template: 模板名称 |
| @EventHandler | Message | 事件处理器 | @ApplicationService @DomainEventConsumer | - name: 处理器名称 - desc: 处理器描述 - template: 模板名称 |
| @Scheduler | Message | 调度器 | @JobProcessor | - name: 调度器名称 - cron: Cron表达式 - desc: 调度器描述 |
| @Transition | Message | 状态转换 | @DomainService | - name: 转换名称 - desc: 转换描述 - fromState: 源状态(必需) - toState: 目标状态(必需) - event: 转换产生的事件 |
| @Steps | Message | 执行步骤 | 任何方法 | - value: 步骤数组 |
DomainObjectType 枚举
@DomainObject注解的type属性使用以下枚举值:
| 枚举值 | 描述 | 对应AssetType |
|---|---|---|
| ENTITY_OBJECT | 实体对象 | DOMAIN_OBJECT |
| AGGREGATE_ROOT | 聚合根 | DOMAIN_OBJECT |
| VALUE_OBJECT | 值对象 | DOMAIN_OBJECT |
AssetType 枚举
@CompileUnit注解的type属性使用以下枚举值,按分组组织:
DTO类型(AssetGroup.DTO)
- REQUEST: 请求对象
- DTO: 数据传输对象
- COMMAND: 命令对象
- QUERY: 查询对象
- VALUE_OBJECT: 值对象
- DOMAIN_EVENT: 领域事件
- DOMAIN_OBJECT: 领域对象
- DATA_MODEL: 数据模型
- ENTITY_MODEL: 实体模型
服务类型(AssetGroup.SERVICE)
- BIZ_CAPACITY_API: 业务能力接口
- BIZ_CAPACITY_CONTROLLER: 业务能力控制器
- BIZ_CAPACITY_DUBBO: 业务能力Dubbo服务
- APPLICATION_SERVICE: 应用服务
- DOMAIN_SERVICE: 领域服务
- DOMAIN_EVENT_CONSUMER: 事件消费者
- JOB_PROCESSOR: 定时任务处理器
基础设施类型(AssetGroup.INFRA)
- CONVERTOR: 转换器
- ENUM: 枚举
- GATEWAY_CLIENT: 网关客户端接口
- GATEWAY_REPOSITORY: 仓储接口
- DATABASE_ENTITY: 数据库实体
- DATABASE_MAPPER: MyBatis Mapper
- GATEWAY_CLIENT_IMPL: 网关客户端实现
- GATEWAY_REPO_IMPL: 仓储实现
- ENTITY_MANAGER: 实体管理器
- RPC_WRAPPER: RPC包装器
- EXTENSION_POINT: 扩展点
- EXTENSION: 扩展实现
@Steps 注解详细说明
@Steps 注解用于定义方法的执行步骤,为AI代码生成提供业务逻辑上下文。
设计理念
- AI友好: 为AI代码生成工具提供结构化的业务逻辑描述
- 可读性: 提高代码的可读性和文档化程度
- 简洁性: 使用简单的字符串数组描述步骤
- 扩展性: 为未来的复杂步骤定义预留扩展空间
使用方式
1. 独立使用@Steps注解
@Steps(["验证用户权限", "检查订单状态", "执行退款操作", "发送通知"])
@CommandHandler({"name": "processRefund"})
void processRefund(RefundCommand command);
2. 在@CommandHandler中使用steps属性
@CommandHandler({
"name": "createOrder",
"steps": ["验证用户信息", "检查库存", "创建订单", "发送确认"]
})
Order createOrder(CreateOrderCommand command);
3. 在@DomainMethod中使用steps属性
@DomainMethod({
"name": "calculateDiscount",
"steps": ["获取用户等级", "应用折扣规则", "计算最终价格"]
})
Decimal calculateDiscount(UserId userId, Amount amount);
优先级规则
当方法同时使用@Steps注解和方法注解的steps属性时:
- @Steps注解优先级最高
- @CommandHandler的steps属性次之
- @DomainMethod的steps属性最低
DDD 完整模式示例
Avro Schema 定义
@namespace("com.example.order")
protocol OrderManagement {
// 订单聚合根
@DomainObject({"domain": "OrderManagement", "name": "Order", "type": "AGGREGATE_ROOT", "desc": "订单聚合根"})
record Order {
@DomainId({"name": "orderId", "desc": "订单唯一标识"})
string id;
@DomainState({"name": "status", "desc": "订单状态"})
string status;
string customerId;
double totalAmount;
long createdAt;
long updatedAt;
@DomainField({"strategy": "EMBEDDED"})
array<OrderItem> items;
}
// 订单项值对象
@DomainObject({"domain": "OrderManagement", "name": "OrderItem", "type": "VALUE_OBJECT", "desc": "订单项值对象"})
record OrderItem {
string productId;
string productName;
int quantity;
double price;
}
// 客户实体
@DomainObject({"domain": "OrderManagement", "name": "Customer", "type": "ENTITY_OBJECT", "desc": "客户实体"})
record Customer {
@DomainId({"name": "customerId", "desc": "客户唯一标识"})
string id;
string name;
string email;
string phone;
@DomainField({"length": 500})
string address;
}
@Command({"domain": "OrderManagement", "name": "CreateOrderCommand", "desc": "创建订单命令"})
record CreateOrderCommand {
string customerId;
array<OrderItem> items;
}
@DomainEvent({"domain": "OrderManagement", "name": "OrderCreated", "desc": "订单创建事件"})
record OrderCreated {
string orderId;
string customerId;
double totalAmount;
long createdAt;
}
@Query({"domain": "OrderManagement", "name": "OrderQuery", "desc": "订单查询"})
record OrderQuery {
string customerId;
string status;
long startDate;
long endDate;
}
}
转换规则
1. Schema 到 Service 转换
@DomainService→ 生成领域服务类@ApplicationService→ 生成应用服务类@BizCapacityApi→ 生成业务能力API接口@BizCapacityService→ 生成业务能力服务实现@JobProcessor→ 生成定时任务处理器@DomainEventConsumer→ 生成事件消费者
2. Record 到 Domain Object 转换
@DomainObject(type="AGGREGATE_ROOT")→ 生成聚合根类@DomainObject(type="ENTITY_OBJECT")→ 生成实体类@DomainObject(type="VALUE_OBJECT")→ 生成值对象类@CompileUnit→ 生成资源对象类@DomainEvent→ 生成领域事件类@Command→ 生成命令类@Query→ 生成查询类
3. Field 到 Property 转换
@DomainId→ 生成标识属性,添加相应的生成策略@DomainState→ 生成状态属性,添加状态验证逻辑@DomainField→ 生成持久化属性,按属性配置映射数据库字段
4. Message 到 Service Method 转换
@DomainMethod→ 生成领域方法@CommandHandler→ 生成命令处理方法@QueryHandler→ 生成查询处理方法@EventHandler→ 生成事件处理方法@Scheduler→ 生成调度方法@Transition→ 生成状态转换方法,配合状态机实现@Steps→ 为生成的方法添加步骤注释和文档
方法职责区分
Command Handler(命令处理器)
- 职责: 处理改变系统状态的操作
- 特征: 有副作用,可能修改数据
- 返回: 通常返回操作结果或void
- 示例: 创建订单、更新用户信息、删除商品
- 步骤支持: 支持steps属性定义执行步骤
Query Handler(查询处理器)
- 职责: 处理查询操作,不改变系统状态
- 特征: 无副作用,只读操作
- 返回: 返回查询结果
- 示例: 获取订单详情、查询用户列表、统计数据
Event Handler(事件处理器)
- 职责: 处理领域事件,实现事件驱动架构
- 特征: 异步处理,解耦系统组件
- 返回: 通常返回void
- 示例: 处理订单创建事件、用户注册事件
Domain Method(领域方法)
- 职责: 实现核心业务逻辑
- 特征: 封装业务规则和约束
- 返回: 根据业务需要返回相应结果
- 示例: 计算订单总价、验证用户权限
- 步骤支持: 支持steps属性定义执行步骤
Scheduler(调度器)
- 职责: 定时执行的任务
- 特征: 按时间规则自动触发
- 返回: 通常返回void
- 示例: 清理过期数据、发送定时报告
Transition(状态转换)
- 职责: 管理实体状态转换
- 特征: 与状态机配合,确保状态转换的合法性
- 返回: 根据转换结果返回相应值
- 示例: 订单状态从”已创建”转换为”已支付”
Steps(执行步骤)
- 职责: 定义方法的执行步骤
- 特征: 为AI代码生成提供业务逻辑上下文
- 用途: 提高代码可读性,辅助代码生成
- 示例: [“验证参数”, “执行业务逻辑”, “返回结果”]
优先级规则
-
类型级注解优先级(从高到低):
@DomainObject(type="AGGREGATE_ROOT")>@DomainObject(type="ENTITY_OBJECT")>@DomainObject(type="VALUE_OBJECT")>@CompileUnit@DomainService>@ApplicationService
-
字段级注解优先级:
@DomainId具有最高优先级@DomainState用于状态管理@DomainField用于持久化字段定制,未标注时按默认策略处理
-
方法级注解优先级:
@CommandHandler、@QueryHandler、@EventHandler具有相同优先级@Transition与状态相关方法配合使用@Scheduler用于定时任务@Steps可与其他方法注解组合使用
-
步骤定义优先级:
@Steps注解 >@CommandHandler.steps>@DomainMethod.steps
命名约定
1. 注解命名
- 使用 Pascal 命名法
- 以功能或用途命名
- 避免缩写,使用完整单词
2. 属性命名
- 使用 camelCase 命名法
- 属性名应该清晰表达其用途
- 布尔类型属性使用 is/has/can 等前缀
3. 生成的类命名
- 保持与 Avro Schema 中定义的名称一致
- 如果未指定名称,使用 Schema/Record 的原始名称
- 添加适当的后缀(如 Service、Repository 等)
最佳实践
1. 注解使用原则
- 单一职责: 每个注解应该有明确的单一职责
- 最小化: 只使用必要的注解,避免过度注解
- 一致性: 在整个项目中保持注解使用的一致性
- 文档化: 为复杂的注解组合提供充分的文档说明
2. 领域对象设计
- 使用
@DomainObject(type="AGGREGATE_ROOT")标记聚合根 - 使用
@DomainObject(type="ENTITY_OBJECT")标记实体 - 使用
@DomainObject(type="VALUE_OBJECT")标记值对象 - 合理使用
@CompileUnit标记非核心业务对象
3. 状态管理
- 使用
@DomainState标记状态字段 - 配合
@Transition定义状态转换规则 - 确保状态转换的原子性和一致性
4. 服务设计
- 领域服务应该是无状态的
- 使用
@CommandHandler和@QueryHandler明确区分命令和查询 - 合理使用
@EventHandler实现松耦合
5. 步骤定义最佳实践
- 简洁明确: 步骤描述应该简洁明确,避免冗长
- 逻辑顺序: 按照实际执行顺序定义步骤
- 适度详细: 既不过于粗糙也不过于细致
- 业务导向: 从业务角度描述步骤,而非技术实现
6. 性能考虑
- 查询操作合理使用缓存
- 长时间运行的操作使用异步处理
- 设置合理的超时和重试策略
扩展机制
1. 自定义注解
可以基于现有注解创建自定义注解:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@DomainService
public @interface OrderService {
String value() default "OrderService";
}
2. 注解组合
支持多个注解的组合使用:
@DomainObject({"domain": "OrderManagement", "name": "Order", "type": "AGGREGATE_ROOT"})
record Order {
// 字段定义
}
3. 步骤扩展
未来可以扩展步骤定义的复杂度:
// 未来可能的扩展
@Steps({
@Step(name="验证参数", condition="input != null"),
@Step(name="执行业务逻辑", errorHandling="retry"),
@Step(name="返回结果")
})
本规范为 Avro 到 DDD 模型转换提供了完整的注解体系,支持灵活的模型映射和代码生成。通过合理使用这些注解,特别是新增的@Steps与@DomainField注解,可以实现高质量的 DDD 模型转换和AI辅助的代码生成。