JPA 与 DDD 的==聚合写== 是绝配,但在 “读” 场景 往往会引发各种性能问题 。这也是很多公司弃用 JPA 而选择 MyBatis 的主要原因,就其本质并不是框架的错,而是将框架用在了错误的场景 。1. 初始 Repository
在 DDD 中,Repository 是一个非常重要的概念,它是领域层的一个组件,用来管理聚合根的生命周期和持久化 。1.1. 核心为状态管理DDD 是由领域对象承载业务逻辑,所有的业务操作均在模型对象上完成,同一聚合上不同的业务操作构成了聚合的生命周期 。
我们以订单为例,如下图所示:
文章插图
- 首先,用户操作下单,使用提交数据为其创建一个 Order 对象,版本 V1;
- 随后,用户进行改地址操作,调用 Order 对象的 modifyAddress 方法,Order 从原来的 V1 变成 V2;
- 用户完成支付后,调用 Order 对象的 paySuccess 方法,Order 从 V2 变成 V3;
1.2. 为什么需要 Repository?假设,有一台非常牛逼的计算机,计算资源无限、内存大小无限、永不掉电、永不宕机,那最简单高效的方式便是将模型对象全部放在内存中 。
但,现实不存在这样的机器,我们不得不将内存对象写入磁盘,下次使用时,在将其从磁盘读入到内存 。
整体结构如下图所示:
文章插图
和上图相比,具有如下特点:
- 业务操作没变,仍旧依次完成 下单、改地址、支付等操作
- 引入持久化存储(MySQL),可以将 Order 对象存储于关系数据库
- 配合 Order 的生命周期,操作中增加 save、load 和 update 等操作
- 用户下单创建 Order 对象,通过 save 方法将 Order 对象持久化到 DB
- 接收到业务操作,需执行load,从 DB 加载数据到内存 并对 Order 对象的状态进行恢复
- 在业务操作完成后,需执行update,将 Order 对象的最新状态同步的 DB
在领域驱动设计(DDD)中,Repository 是一种设计模式,它是用来存储领域对象的容器 。它提供了一种统一的方式来查询和存储领域对象 。Repository提供了对底层数据存储的抽象,允许应用程序在没有直接与数据存储技术交互的情况下访问数据,同时该抽象允许在不修改应用程序代码的情况下更改数据存储技术 。
【注】在 DDD 中,Repository 并不是一个 DAO,它的职责比 DAO 要多得多,它管理的是整个聚合根,而不是单个实体对象 。同时,Repository 还需要提供一些查询接口,用来查询聚合根的状态 。
2. 什么是好的 Repository?Repository 主要用于完成对聚合根生命周期的管理,所以必须提供三组操作:
- 保存 。将聚合根同步到底层存储进行持久化处理;
- 查询 。根据 ID 或属性从底层存储引擎中读取数据并恢复为内存对象,也就是聚合根对象;
- 更新 。聚合对象发生变更后,可以将新的状态同步到存储引擎,以便完成数据更新;
DAO 是单表单实体操作,Repository 操作的是整个聚合甚至包括继承关系,这就是最大的区别 。也就是Repository 必须能够:
- 维护一个完整的对象组,也就是必须能处理对象的组合关系;
- 维护一个完整的继承体系,也就是必须能够处理对象继承关系;
那就完了吗?并没有!!!
聚合根是一个对象组,包含各种关系,并不是每个业务操作都需要聚合根内的所有实体 。
举个例子,在电商订单聚合根内,包括:
- 订单(Order) 。记录用户的一次生单,主要保存用户、支付金额、订单状态等;
- 订单项(OrderItem) 。购买的单个商品,主要保存商品单价、售价、应付金额等;
推荐阅读
- 解密MongoDB的数据分片策略与负载均衡:构建可伸缩的数据库
- 深度解密大模型的“军火商”,向量数据库的八大技术方向!
- 解密成功程序员的秘密武器
- 解密《穿普拉达的女王》,突破刻板印象,绽放女性职场之光
- 无头浏览器解密:全面了解这个神秘的工具
- 企业服务器数据库中了_locked勒索病毒怎么解密,_locked勒索病毒简介与防护
- OpenAI API新功能解密:成本大幅下降,体验感飙升
- DDD实战 - Repository模式的妙用
- 为什么从 MVC 到 DDD,架构的本质是什么?
- DDD 中关于应用架构的那些事