在领域驱动设计(DDD)中,如何区分业务相关性与技术相关性
区分业务相关性与技术相关性是保持领域模型纯净性的关键。以下是判断标准、具体示例和操作指南:
1. 核心判断标准
一个功能或数据是否属于业务相关,可通过以下问题判断:
问题 | 回答为“是” → 业务相关 | 回答为“否” → 技术相关 |
---|---|---|
是否直接影响业务决策或业务流程? | ✅ | ❌ |
是否使用业务术语(Ubiquitous Language)命名? | ✅ | ❌ |
是否需要遵循明确的业务规则或约束? | ✅ | ❌ |
是否属于业务专家关心的核心领域概念? | ✅ | ❌ |
变更时是否需要与业务专家协商? | ✅ | ❌ |
2. 具体场景示例
(1) 业务相关(应放入领域层)
- 数据表/实体:
Order
(订单)、Payment
(支付)、Inventory
(库存)- 原因:直接影响核心业务流程,包含业务规则(如订单金额校验)。
- 字段或行为:
Order.CalculateTotalPrice()
(计算订单总价,含折扣逻辑)Product.IsOutOfStock
(商品是否缺货,影响下单流程)- 原因:直接体现业务逻辑。
(2) 技术相关(应放入基础设施层)
- 数据表/实体:
AuditLog
(审计日志)、ApiRequestLog
(API请求日志)- 原因:记录技术操作,不参与业务决策(除非是业务审计需求)。
- 字段或行为:
User.LastLoginTime
(最后登录时间)DatabaseMigrationHistory
(数据库迁移记录)- 原因:用于技术监控或系统维护,与业务无关。
3. 模糊场景的进一步分析
(1) 日志记录
- 业务日志(需领域层):
- 记录用户关键操作(如
OrderCancelledLog
),供业务分析或审计。 - 特征:包含业务语义(如操作类型、业务实体ID)。
- 记录用户关键操作(如
- 技术日志(需基础设施层):
- 记录系统错误、API响应时间。
- 特征:仅用于调试或监控系统健康度。
(2) 缓存机制
- 业务缓存(可能涉及领域层):
- 缓存商品详情页的聚合数据(如库存+价格+促销)。
- 特征:缓存内容直接支持业务展示逻辑。
- 技术缓存(基础设施层):
- 缓存数据库连接、JWT Token。
- 特征:纯技术优化,与业务无关。
4. 误区和注意事项
(1) 常见误区
- 误区一:将所有数据库表都当作领域实体。
正确做法:仅核心业务表属于领域层(如Order
),技术表(如Log
)属于基础设施层。 - 误区二:在领域层引用技术框架(如
HttpContext
)。
正确做法:通过依赖抽象(接口)隔离技术细节。
(2) 设计原则
- 单一职责:领域层只关注业务逻辑,基础设施层处理技术实现。
- 依赖倒置:领域层定义接口,基础设施层实现接口(如
IAuditLogRepository
)。 - 领域事件驱动:用领域事件解耦业务动作和技术操作(如发邮件、写日志)。
5. 实战:如何为 TLog
表分类?
假设 TLog
表用于记录用户操作,需判断其归属:
- 场景一:记录用户登录、退出时间 → 技术日志(基础设施层)。
- 场景二:记录用户下单、支付行为 → 业务日志(领域层实体
UserActionLog
)。 - 场景三:记录系统异常堆栈 → 技术日志(基础设施层)。
总结
- 业务相关性 = 直接影响核心业务流程 + 使用业务语言 + 包含业务规则。
- 技术相关性 = 支持系统运行 + 不涉及业务决策 + 无业务语义。
通过明确分层,确保领域模型专注于业务复杂性,技术细节由基础设施层处理。