领域建模技能指南 m09-domain

本指南是关于领域驱动设计(DDD)在Rust语言中的实践应用,详细讲解了如何将领域概念(如实体、值对象、聚合)映射到Rust的代码模式。它提供了核心设计原则、思考框架、模式模板和常见错误分析,旨在帮助开发者构建类型安全、符合业务规则且易于维护的领域模型。关键词:领域驱动设计,DDD,Rust编程,软件架构,业务建模,实体,值对象,聚合,类型安全,代码设计。

架构设计 0 次安装 0 次浏览 更新于 2/27/2026

name: m09-domain description: “关键:用于领域建模。触发词:领域模型,DDD,领域驱动设计,实体,值对象,聚合,仓储模式,业务规则,验证,不变条件,领域模型,领域驱动设计,业务规则” user-invocable: false

领域建模

第2层:设计选择

核心问题

这个概念在领域中的角色是什么?

在代码建模之前,请理解:

  • 它是一个实体(身份重要)还是一个值对象(可互换)?
  • 必须维护哪些不变条件?
  • 聚合边界在哪里?

领域概念 → Rust 模式

领域概念 Rust 模式 所有权含义
实体 struct + Id 拥有,唯一身份
值对象 struct + Clone/Copy 可共享,不可变
聚合根 struct 拥有子项 清晰的所有权树
仓储 trait 抽象持久化
领域事件 enum 捕获状态变化
服务 impl 块 / 自由函数 无状态操作

思考提示

在创建领域类型之前:

  1. 概念的身份是什么?

    • 需要唯一身份 → 实体(Id 字段)
    • 按值可互换 → 值对象(Clone/Copy)
  2. 必须保持哪些不变条件?

    • 始终有效 → 私有字段 + 已验证的构造函数
    • 转换规则 → 类型状态模式
  3. 谁拥有这些数据?

    • 单一所有者(父级) → 拥有的字段
    • 共享引用 → Arc/Rc
    • 弱引用 → Weak

向上追溯 ↑

到领域约束(第3层):

"我应该如何建模一个交易?"
    ↑ 问:哪些领域规则管理交易?
    ↑ 检查:domain-fintech(审计,精度要求)
    ↑ 检查:业务干系人(哪些不变条件?)
设计问题 追溯到 提问
实体 vs 值对象 domain-* 什么使两个实例“相同”?
聚合边界 domain-* 什么必须保持一致?
验证规则 domain-* 哪些业务规则适用?

向下追溯 ↓

到实现(第1层):

"建模为实体"
    ↓ m01-ownership: 拥有,唯一
    ↓ m05-type-driven: Id 的新类型

"建模为值对象"
    ↓ m01-ownership: Clone/Copy 可行
    ↓ m05-type-driven: 在构造时验证

"建模为聚合"
    ↓ m01-ownership: 父级拥有子级
    ↓ m02-resource: 考虑在聚合内共享时使用 Rc

快速参考

DDD 概念 Rust 模式 示例
值对象 新类型 struct Email(String);
实体 结构体 + ID struct User { id: UserId, ... }
聚合 模块边界 mod order { ... }
仓储 特征 trait UserRepo { fn find(...) }
领域事件 枚举 enum OrderEvent { Created, ... }

模式模板

值对象

struct Email(String);

impl Email {
    pub fn new(s: &str) -> Result<Self, ValidationError> {
        validate_email(s)?;
        Ok(Self(s.to_string()))
    }
}

实体

struct UserId(Uuid);

struct User {
    id: UserId,
    email: Email,
    // ... 其他字段
}

impl PartialEq for User {
    fn eq(&self, other: &Self) -> bool {
        self.id == other.id  // 身份相等性
    }
}

聚合

mod order {
    pub struct Order {
        id: OrderId,
        items: Vec<OrderItem>,  // 拥有的子项
        // ...
    }

    impl Order {
        pub fn add_item(&mut self, item: OrderItem) {
            // 强制执行聚合不变条件
        }
    }
}

常见错误

错误 为什么错 更好的做法
原始类型偏执 没有类型安全 新类型包装器
带有不变条件的公共字段 不变条件被破坏 私有 + 访问器
泄露聚合内部 封装被破坏 根上的方法
使用字符串表示语义类型 没有验证 已验证的新类型

相关技能

何时 参见
类型驱动的实现 m05-type-driven
聚合的所有权 m01-ownership
领域错误处理 m13-domain-error
特定领域规则 domain-*