跳到主要内容
版本:Next

领域模型设计

本文档引用的文件

目录

  1. 引言
  2. 聚合根结构与行为
  3. 实体字段定义
  4. 审计能力继承
  5. 工厂方法与构造逻辑
  6. 业务规则验证逻辑
  7. 状态变更行为
  8. 规格模式应用
  9. 领域事件机制
  10. 事件处理响应
  11. 值对象与不变性约束
  12. 领域服务边界
  13. UML类图建议
  14. 状态转换图

引言

本文档详细描述了MyEntityName作为领域驱动设计中的核心聚合根的完整领域模型。该模型体现了典型的DDD实践,包括聚合根、规格模式、领域事件、仓储接口等关键概念。通过分析其结构、行为和交互关系,帮助开发人员理解该领域的核心设计原则和实现方式。

聚合根结构与行为

MyEntityName是领域模型中的核心聚合根,继承自FullAuditedAggregateRoot<Guid>,封装了业务逻辑、数据完整性和行为规则。作为聚合根,它负责维护内部一致性,并通过明确定义的方法暴露可变操作。

Section sources

实体字段定义

MyEntityName聚合根包含以下核心字段,均通过受保护的set访问器确保只能通过领域方法进行修改:

  • Code: 编号,字符串类型,最大长度由MyEntityNameConsts.MaxCodeLength定义(默认64)
  • Name: 名称,字符串类型,最大长度由MyEntityNameConsts.MaxNameLength定义(默认64)
  • Sort: 排序,整数类型,用于排序展示
  • Remark: 备注,字符串类型,最大长度由MyEntityNameConsts.MaxRemarkLength定义(默认256)
  • IsDisabled: 是否禁用,可空布尔类型,表示实体状态

所有字段均使用virtual关键字,支持EF Core的延迟加载和代理功能。

Section sources

审计能力继承

MyEntityName继承自FullAuditedAggregateRoot<Guid>,自动获得完整的审计能力,包括:

  • CreationTime: 创建时间
  • CreatorId: 创建者ID
  • LastModificationTime: 最后修改时间
  • LastModifierId: 最后修改者ID
  • IsDeleted: 是否已删除(软删除)
  • DeleterId: 删除者ID
  • DeletionTime: 删除时间

这些审计字段由框架自动管理,无需在业务代码中手动设置,确保了审计信息的一致性和可靠性。

Section sources

工厂方法与构造逻辑

MyEntityName提供了两种构造方式:

  1. 受保护的无参构造函数:供ORM框架反序列化使用
  2. 公共有参构造函数:作为工厂方法创建新实例,接收idcodename等必要参数,并执行基础验证

构造过程中通过Check.NotNullOrWhiteSpaceCheck.Length等断言方法确保输入数据的有效性,体现了"不变性在构造时建立"的设计原则。

Section sources

业务规则验证逻辑

业务规则验证贯穿于整个生命周期,主要体现在:

  • 构造时验证:确保codename非空且长度合规
  • 更新时验证:在Update方法中重新验证codenameremark
  • 应用服务层验证MyEntityNameAppService在创建/更新前检查名称唯一性
  • 导入时验证:批量导入时检查行级数据完整性和名称重复

验证逻辑遵循"快速失败"原则,一旦发现违规立即抛出有意义的异常。

Section sources

状态变更行为

MyEntityName支持以下状态变更操作:

  • Update: 更新codenameremarkisDisabled字段
  • AdjustSort: 调整排序值,支持重新排序逻辑
  • Clone: 克隆实体,生成新ID并追加"_副本"后缀

这些方法均在聚合根内部实现,确保状态变更的原子性和一致性。特别是AdjustSort方法,支持复杂的排序调整逻辑,包括上移、下移和指定位置插入。

Section sources

规格模式应用

MyEntityNameSpecification实现了规格模式(Specification Pattern),用于构建可复用的查询条件:

  • 用途:在仓储层封装复杂的查询逻辑,提高代码可读性和可测试性
  • 实现:继承自Volo.Abp.Specifications.Specification<T>,重写ToExpression方法
  • 参数化:支持通过name参数动态构建查询条件
  • 组合性:可通过AndOr等操作符组合多个规格

该规格在MyEntityNameAppService.GetListAsync中被实际使用,实现了按名称过滤的功能。

Diagram sources

Section sources

领域事件机制

MyEntityName通过MyEntityNameEto(事件传输对象)发布领域事件:

  • 事件定义MyEntityNameEto包含Name属性,用于传递事件上下文
  • 事件发布:虽然当前代码未显示发布逻辑,但架构已准备好通过IDistributedEventBus发布事件
  • 事件消费:支持分布式事件处理,确保跨服务的一致性

领域事件模式解耦了业务逻辑与副作用操作(如发送通知、更新索引等)。

Diagram sources

Section sources

事件处理响应

MyEntityNameEventHandler实现了对MyEntityNameEto事件的响应:

  • 实现接口:实现IDistributedEventHandler<MyEntityNameEto>ITransientDependency
  • 处理逻辑:当前为空实现(Task.CompletedTask),作为扩展点预留
  • 生命周期:瞬态依赖,每次事件触发都会创建新实例

该处理器可在分布式环境中响应来自其他服务的事件,实现跨边界上下文的集成。

Section sources

值对象与不变性约束

本模型中未明确定义值对象,但体现了值对象的设计思想:

  • 不变性约束:通过常量类MyEntityNameConsts集中管理字段长度等约束
  • 克隆标记MyEntityNameConsts.CloneTag定义了克隆时的后缀规则
  • 数据种子MyEntityNameDataSeedContributor确保测试数据的一致性

这些设计共同维护了领域的不变性规则。

Section sources

领域服务边界

领域服务边界清晰,遵循分层架构:

  • 领域层MyEntityNameMyEntityNameSpecificationMyEntityNameEto
  • 仓储接口IMyEntityNameRepository定义数据访问契约
  • 应用服务MyEntityNameAppService编排领域对象,不包含核心业务规则
  • DTO层MyEntityNameCreateDtoMyEntityNameUpdateDto用于数据传输

这种分层确保了领域模型的纯粹性,避免业务逻辑泄露到应用层。

Diagram sources

UML类图建议

Diagram sources

状态转换图

Diagram sources