当前位置: 首页 > news >正文

DDD领域驱动中瘦模型与富态模型的核心区别

🧠 DDD领域驱动中瘦模型与富态模型的核心区别

引用

  1. 最肯忘卻古人詩 最不屑一顧是相思
  2. 春又來看紅豆開 竟不見有情人去采

🧬 1. 核心定义与哲学思想

🏁 瘦模型(Anemic Model)

【定义】 只包含数据字段和基础getter/setter方法的“哑对象”,业务逻辑外置于服务层
【哲学】 源自面向过程思想,强调“数据与行为分离”,类似于C语言结构体。
C++结构示例 📐:

// 纯数据载体
class CustomerAnemic {
public:std::string name() const { return name_; }void setName(const std::string& name) { name_ = name; }double balance() const { return balance_; }void setBalance(double balance) { balance_ = balance; } private:std::string name_;double balance_ = 0.0;
};// 业务逻辑在服务类中
class CustomerService {
public:void deductBalance(CustomerAnemic& customer, double amount) {if (amount > customer.balance())throw std::runtime_error("Insufficient balance");customer.setBalance(customer.balance() - amount);}
};
🏁 富态模型(Rich Model)

【定义】 数据与行为高度内聚的领域对象,封装业务规则和状态变更逻辑。
【哲学】 遵循面向对象设计原则,核心是“高内聚、低耦合”和“封装不变性”。
C++实现 📐:

class CustomerRich {
public:CustomerRich(const std::string& name, double balance) : name_(name), balance_(balance) {}void deductBalance(double amount) {if (amount > balance_) throw std::runtime_error("Insufficient balance");balance_ -= amount;addTransaction("DEDUCT", amount); // 内部状态联动}void addTransaction(const std::string& type, double amount) {transactions_.push_back({type, amount});}private:std::string name_;double balance_;std::vector<std::pair<std::string, double>> transactions_;
};

🔍 2. 本质区别可视化对比

维度🪫 瘦模型🔋 富态模型
业务逻辑位置❗ 位于Service层✅ 封装在领域对象内部
领域对象角色📦 数据容器(类似DTO)⚙️ 自治的行为主体
状态变更控制⚠️ 外部服务类直接修改状态✅ 仅通过对象方法内部修改
业务规则表达力📉 规则散布在服务类中📈 通过对象方法自然展现领域规则
与DDD的契合度❌ 违反DDD聚合根设计原则✅ 完美实现DDD聚合根概念
数据一致性边界🔓 跨对象逻辑需事务管理🔒 聚合根内天然一致性保证
⭐ 关键区别示意图

在这里插入图片描述


🎯 3. 应用场景深度分析

💡 瘦模型适用场景
  1. 简单CRUD系统:如后台管理系统,业务规则少
  2. 需极简架构场景:微服务间数据传输(DTO模式)
  3. 重度依赖框架的遗留系统:如使用Hibernate且需脱离数据库逻辑
  4. 高性能要求场景:避免对象方法调用开销
💡 富态模型适用场景
  1. 复杂业务核心域:如电商交易系统、风控引擎
  2. 领域逻辑频繁变更:封装变化点降低维护成本
  3. 需强一致性保证:如银行账户扣款+流水记录原子操作
  4. 业务规则易用性优先:降低Service层复杂度

⚖️ 4. 优劣势深度剖析

🛡️ 富态模型核心优势
优势原理说明DDD设计影响
领域自洽性💎 对象自含完整性校验逻辑(如 deductBalance()实现聚合根的自治性
高可维护性🔧 业务变更仅需修改领域对象契合限界上下文(Bounded Context)
表达领域语言🗣️ 方法名如 placeOrder() 直接映射领域事件强化统一语言(Ubiquitous Language)
防贫血设计🩸 根治Martin Fowler提出的贫血模型问题符合DDD战术设计原则
并发控制优化🔒 聚合根内提供乐观锁实现点简化事务边界管理
⚠️ 富态模型潜在局限
  1. 对象膨胀风险 ➜ 方法过多时破坏单一职责原则
  2. 框架适配困难 ➜ ORM框架需支持复杂领域逻辑
  3. 学习曲线陡峭 ➜ 需深入理解DDD和OOP设计思想
  4. 性能开销 ➜ 领域对象内聚导致单次操作耗时增加

🧩 5. 实践案例:电商订单系统的对比

🛒 订单处理逻辑实现对比

瘦模型实现(业务逻辑外置):

// OrderService.cpp
void OrderService::placeOrder(OrderAnemic& order) {if (order.items().empty()) throw InvalidOrder();double total = 0;for (auto& item : order.items()) {total += item.price() * item.quantity();}order.setTotal(total);  // 外部修改状态if (!PaymentService::pay(order.user(), total)) throw PaymentFailed();InventoryService::deductItems(order.items()); // 跨服务调用order.setStatus(PLACED); // 状态变更分散
}

富态模型实现(业务逻辑内聚):

// OrderRich.cpp
void OrderRich::placeOrder() {if (items_.empty()) throw InvalidOrder();total_ = calculateTotal(); // 内部方法处理status_.attemptTransition(PLACING); // 状态机模式auto payment = std::make_shared<Payment>(user_, total_);payment->execute();  // 领域事件驱动if (payment->isSuccess()) {items_.deductInventory(); // 领域内聚合协作status_.setStatus(PLACED);} else {status_.setStatus(FAILED);throw PaymentFailed();}
}
🚦 关键差异点说明
  1. 状态变更:富态模型中status_由内部状态机控制
  2. 业务规则:总价计算封装在calculateTotal()私有方法
  3. 事务边界:聚合根OrderRich保证订单操作原子性
  4. 领域协作:直接调用ItemList子实体的业务方法

🧭 6. 混合应用策略建议

  1. 分层架构平衡 ⚖️
    简单操作
    UI层
    应用层
    领域层-Rich Model
    基础设施层
    基础服务层-Anemic
  2. 场景化选择原则
    • 核心域 ➜ 100%富态模型
    • 支撑子域 ➜ 瘦模型加速开发
    • 通用子域 ➜ 混合设计
  3. 技术适配方案 🧰
    • ORM框架使用EF Core或Hibernate支持聚合根
    • 复杂逻辑采用领域服务补充

🧪 7. 富态模型设计进阶技巧

  1. 状态模式应用
class OrderStatus {
public:virtual void ship(OrderRich& order) = 0;// 其他状态方法...
};class PlacedStatus : public OrderStatus {
public:void ship(OrderRich& order) override {order.notifyShipped();order.setStatus(std::make_unique<ShippedStatus>());}
};
  1. 领域事件驱动
class OrderRich {
public:void addDomainEvent(std::unique_ptr<DomainEvent> event) {domainEvents_.push_back(std::move(event));}void publishEvents() {for (auto& event : domainEvents_) DomainEventPublisher::publish(*event);domainEvents_.clear();}
private:std::vector<std::unique_ptr<DomainEvent>> domainEvents_;
};

🔚 8. 结论

瘦模型作为简单的数据传输结构,在非核心领域可提供快速实现方案。而富态模型作为DDD的战术核心,通过内聚领域逻辑,在构建复杂业务系统时提供:
✅ 更清晰的业务语义表达
✅ 更强的模型一致性保证
✅ 更高的内聚度和可维护性


💎 决策矩阵
在这里插入图片描述

建议:在战略层面识别核心域,富态模型投入产出比可达10:1;在战术实施中优先保证聚合根的完整性设计加粗样式

http://www.lryc.cn/news/602373.html

相关文章:

  • FastGPT本地构建工作流高级编排(最新4.11.0)
  • 火狐浏览器中国特供版关闭,如何下载 Firefox 国际版?如何备份数据?
  • App Inventor 2 使用 MaterialIcons 图标字体,快捷展示专业图标
  • NAS远程访问新解法:OMV与cpolar的技术协同价值
  • CentOS7 安装和配置教程
  • nvim tagbar安装
  • VUE2 学习笔记11 脚手架
  • 架构实战——互联网架构模板(“存储层”技术)
  • 黑马商城微服务-下
  • 云服务器以域名形式访问机房Kubernetes集群服务之解决方案
  • 国产化PDF处理控件Spire.PDF教程:Java 提取 PDF 图片,高质量提取与图片过滤技巧
  • 【设计模式】状态模式 (状态对象(Objects for States))
  • Spring AI 1.0 提供简单的 AI 系统和服务
  • claude code
  • LeetCode 85. 最大矩形
  • 剑指“CPU飙高”问题
  • FFmpeg 安装与使用
  • kafka开启Kerberos使用方式
  • 【三桥君】如何解决后端Agent和前端UI之间的交互问题?——解析AG-UI协议的神奇作用
  • 2025年7月28日训练日志
  • Android 解析 TrafficDescriptor 的 OSAPP 信息
  • Android15广播ANR的源码流程分析
  • ubuntu安装Anaconda及应用
  • 【运维】HuggingFace缓存目录结构详解
  • 首个智能存力调度平台启动!与算力网络共同加速AI创新
  • 【深度学习】SOFT Top-k:用最优传输解锁可微的 Top-k 操作
  • 应急响应案例处置(下)
  • 应急响应处置案例(上)
  • 【LeetCode 热题 100】(一)哈希
  • 绿算技术携手昇腾发布高性能全闪硬盘缓存设备,推动AI大模型降本增效