我是用的是一个类似 Mybatis 的 ORM,很显然它不支持透明的持久化。聚合根在每次更新之后如何在 Repository 中识别到这些更新并持久化到数据库中。
在《实现领域驱动设计》中作者提到的两种方式
我现在的问题是:
是不是这种半自动化 ORM+关系型数据( MYSQL )无法实现 DDD
或者实现的代价比较大(如在聚合根内部保存所有的操作记录,然后再 Repository 中根据这些记录持久化)
或者是必须使用 Event Source 这种方法来持久化(对于我来说太重了)
1
ChoateYao 2019-04-16 10:48:12 +08:00
1. 可以实现
2. 这是一种思路 3. Event Source 并不是这么用的 第二种思路切分出来,使用 Domain Service 手动解决。 要不然你自己完善基础设施层,让 Repository 支持。 |
2
gsj987 2019-04-16 10:51:43 +08:00
一般使用 UnitOfWork 模式 来感知 Repository 的变化,或简单的把显式的操作放在 Application 层
|
3
lihongjie0209 OP |
4
lihongjie0209 OP |
5
ChoateYao 2019-04-16 11:13:14 +08:00
@lihongjie0209 实际情况就是基础设施层没做好的,作出的妥协。
因为你不可能在 Application Layer 做数据拼装然后持久化,落地一个理念根据目前的情况不断做调整以达到最优情况。 |
6
ChoateYao 2019-04-16 11:15:47 +08:00
|
7
gsj987 2019-04-16 11:25:44 +08:00
@lihongjie0209 我指的是在 application 层对 repository 的显式调用,比如你说的 update。在实践中,repository 会用 IRepository 的形式作为基础设施服务,这样 application 就和具体的 orm 解除关联了。当然一般情况下,都会使用基础框架的 UoW 完成隐式更新。
|
8
lihongjie0209 OP |
9
gsj987 2019-04-16 13:50:28 +08:00
@lihongjie0209 这里篇文章讲了具体的实现 https://github.com/sheng-jie/UnitOfWork 。
因为 UoW 统一了持久化方法和事务,所以就可以用 AOP 的方式在框架层面对 UoW 进行隐式调用,如 ABP 的做法: http://www.cnblogs.com/1zhk/p/5309043.html UoW 的作用是追踪 entity 在多个仓库间变化的依赖关系,自动帮你解决事务方法,让事务和持久化在多个聚合中保持统一,但是 IRepsoitory 的方法调用还是需要的。如果你的意思就 tracking changes 然后不调用 IRepository 更新的话,这个可能需要 orm 本身的支持。 |
10
lihongjie0209 OP @gsj987
感谢你的回复,我下去也看了 UOW, 发现一个问题 UOW 的核心是对对象的状态标记, 如果 被修改, 被删除之类的。 我找一个图, 可以帮忙说明一下吗? https://imgur.com/HePiXYq |
11
gsj987 2019-04-19 10:12:54 +08:00
@lihongjie0209 明白你的意思了。这个确实和 UoW 的概念没太大关系,UoW 主要作用就是事务。DDD 的设计战术之一就是一次操作只能修改一个 AR,所以需要 Domain Event 之类的东西来做关联,UoW 让各 AR 实现最终一致。
你这个例子中,确实没法在 Domain 或者 Application 层做相关的操作,因为对 Domain 他不关心持久化,对 Application 他只能看到 AR,不知道里面具体的实现。 这里你提问的半自动化 ORM,就是类似 Dapper 这样的吧?这些 micro-ORM 更多关注的是 M,而像 Hibernate 或者 EF 之类的更多的关注的是 O,也就是说前者还是一个面向数据库,效率高,透明轻快,而后者是面向对象,但是重量,不透明。在 DDD 中,领域对数据库无感知,甚至很多实践还强调聚合根里能用值对象就用值对象,所以无法在 Domain 中体现从对象关系变化映射到数据库变化的关联,这些都是由 Repository 完成的。 那么在如 EF 中,这种关联是自动实现的,因为他有 changetracker,另一方面,他还自己实现了 UoW。而 micro-ORM 没有这些,那就只能手动来做。具体的可以在 Repository 的实现中,对 AR 下的各 entity 的修改进行检查、保存。代价就是每一个特殊的检查都需要手动实现(或者如你的思路 2,自己实现一个 changetracker,如 Dapper.Contrib 就有类似的实现)。另外有些思路中,会拿 ORM 和 micro-ORM 混用,取两者的优点于一身 https://msdn.microsoft.com/zh-cn/magazine/mt703432.aspx |