一佳技术

Avro 到 DDD 模型转换注解规范

本文档定义了用于 Avro IDL 到 MdBlueprint DDD 模型转换的注解规范。这些注解用于标记 Avro Schema 中的元素,指导转换器生成相应的 DDD 模型组件。

注解分类

1. 类型级注解(Type-Level Annotations)

用于标记 Protocol 和 Record 的注解。

注解名称适用元素领域设计元素属性
@CompileUnitRecord
Protocol
通用资源- module: 模块名称
- domain: 所属领域
- name: 资源名称
- desc: 资源描述
- type: 资源类型(参照AssetType枚举)
- template: 模板名称
@BizCapacityApiProtocol业务能力API服务- name: API服务名称
- desc: API服务描述
@BizCapacityServiceProtocol业务能力服务- name: 服务名称
- desc: 服务描述
@DomainServiceProtocol领域服务- domain: 所属领域
- name: 服务名称
- desc: 服务描述
@DomainObjectRecord领域对象- domain: 所属领域
- name: 对象名称
- type: 对象类型(参照DomainObjectType枚举)
- desc: 对象描述
@CommandRecord命令- domain: 所属领域
- name: 命令名称
- desc: 命令描述
@ApplicationServiceProtocol应用服务- domain: 所属领域
- name: 服务名称
- desc: 服务描述
@QueryRecord查询- domain: 所属领域
- name: 查询名称
- desc: 查询描述
@JobProcessorProtocol定时任务处理器- domain: 所属领域
- name: 处理器名称
- desc: 处理器描述
@DomainEventConsumerProtocol领域事件消费者- domain: 所属领域
- name: 消费者名称
- desc: 消费者描述
@DomainEventRecord领域事件- domain: 所属领域
- name: 事件名称
- desc: 事件描述

2. 字段级注解(Field-Level Annotations)

用于标记记录字段的注解。

注解名称适用元素领域设计元素适用父级元素属性
@DomainIdField领域标识@DomainObject- name: 标识名称
- desc: 标识描述
@DomainStateField领域状态@DomainObject- name: 状态字段名称
- desc: 状态描述
@DomainFieldField领域字段@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)

用于标记协议消息的注解。

注解名称适用元素领域设计元素适用父级元素属性
@DomainMethodMessage领域方法@DomainService
@ApplicationService
- name: 方法名称
- desc: 方法描述
- template: 模板名称
- steps: 执行步骤数组
@CommandHandlerMessage命令处理器@DomainService
@ApplicationService
- name: 处理器名称
- desc: 处理器描述
- template: 模板名称
- steps: 执行步骤数组
@QueryHandlerMessage查询处理器@ApplicationService- name: 处理器名称
- desc: 处理器描述
- template: 模板名称
@EventHandlerMessage事件处理器@ApplicationService
@DomainEventConsumer
- name: 处理器名称
- desc: 处理器描述
- template: 模板名称
@SchedulerMessage调度器@JobProcessor- name: 调度器名称
- cron: Cron表达式
- desc: 调度器描述
@TransitionMessage状态转换@DomainService- name: 转换名称
- desc: 转换描述
- fromState: 源状态(必需)
- toState: 目标状态(必需)
- event: 转换产生的事件
@StepsMessage执行步骤任何方法- 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属性时:

  1. @Steps注解优先级最高
  2. @CommandHandler的steps属性次之
  3. @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代码生成提供业务逻辑上下文
  • 用途: 提高代码可读性,辅助代码生成
  • 示例: [“验证参数”, “执行业务逻辑”, “返回结果”]

优先级规则

  1. 类型级注解优先级(从高到低):

    • @DomainObject(type="AGGREGATE_ROOT") > @DomainObject(type="ENTITY_OBJECT") > @DomainObject(type="VALUE_OBJECT") > @CompileUnit
    • @DomainService > @ApplicationService
  2. 字段级注解优先级:

    • @DomainId 具有最高优先级
    • @DomainState 用于状态管理
    • @DomainField 用于持久化字段定制,未标注时按默认策略处理
  3. 方法级注解优先级:

    • @CommandHandler、@QueryHandler、@EventHandler 具有相同优先级
    • @Transition 与状态相关方法配合使用
    • @Scheduler 用于定时任务
    • @Steps 可与其他方法注解组合使用
  4. 步骤定义优先级:

    • @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辅助的代码生成。