mryqr-com / mry-backend

本代码库为码如云后端代码。码如云是一个基于二维码的一物一码管理平台,可以为每一件“物品”生成一个二维码,手机扫码即可查看物品信息并发起相关业务操作,操作内容可由你自己定义,典型的应用场景包括固定资产管理、设备巡检以及物品标签等。在技术上,码如云是一个无代码平台,全程采用DDD、整洁架构和事件驱动架构思想完成开发。
https://www.mryqr.com
GNU General Public License v3.0
216 stars 60 forks source link

关于DDD种聚合根以及仓储层的一些疑惑 #3

Open Chenchicheng opened 1 year ago

Chenchicheng commented 1 year ago

首先对作者表达感谢,因为市面上真正落地且开源的DDD项目少得可怜,感谢作者开发了码如云项目为我们提供了一个DDD讨论之所。 我的问题是资源层除了返回聚合根,是否还能返回非聚合根?因为在这篇文章中,作者提到“资源库方法所接受的参数和返回的数据都应该是聚合根对象是返回聚合根”,但是查看代码却发现非聚合根也被返回了,这是否有冲突? image image

davenkin commented 12 months ago

这里的确返回了一个非聚合根TenantCachedMember,这个TenantCachedMember用于返回缓存的Member,其主体依然是个Member,从大的原则上来说并未违反repository对应聚合根的原则,只是在具体实现上有些变种。

davenkin commented 12 months ago

另外,针对你上述的两张图片,第一张中的代码我在项目早期的确是这么坚持的,到了后期我感觉需要加入缓存了,便在MemberRepository中加入了更多的方法。一开始很多查询方法我并没有放到Repository中,感觉那应该是另一个关注点,但是后来感觉如果有一个集中的地方放置数据库相关的东西,以后如果需要更换数据库的话可能会简单一些,于是我将查询方法也放到了Repository中。这个决定我理解更多是个偏好选择问题,因人而异,但是重要的时,无论做什么选择,保持整个项目范围内的风格一致性可能是更加重要的。

Chenchicheng commented 11 months ago

感谢作者的回复,收获很大。我还有一个问题:作者你使用的是mongo作为数据库存储,这种文档型数据跟DDD架构结合起来的优势是显而易见的,但如果只是单纯的用mysql呢,这时候就会遇到聚合根不好拆分的问题,比如我只想要聚合根里面的某个对象,其他对象要不要都没关系,那么这种情况是不是还得把整个聚合根的所有信息都填充好才返回呢?这样做又会浪费资源,请问作者是怎么处理的?

davenkin commented 11 months ago

这里涉及到一个思维方式的变化,之前的数据库操作我们总希望在写数据时仅仅更新需要更新的字段,而读数据时仅仅加载需要的字段。但是在DDD中,更建议的方式是在建模时不要去思考数据库,而是将聚合根始终当做一个整体来看待,不仅仅是从模型上是这样,在处理持久化的时候也是如此。所以,对于你的问题,是的,需要将整个聚合根填充好。

yeahfo commented 4 months ago

感谢作者的回复,收获很大。我还有一个问题:作者你使用的是mongo作为数据库存储,这种文档型数据跟DDD架构结合起来的优势是显而易见的,但如果只是单纯的用mysql呢,这时候就会遇到聚合根不好拆分的问题,比如我只想要聚合根里面的某个对象,其他对象要不要都没关系,那么这种情况是不是还得把整个聚合根的所有信息都填充好才返回呢?这样做又会浪费资源,请问作者是怎么处理的?

他以前使用 ID, JSON_CONTENT 如果不是强迫症,能够容忍聚合根头上顶着一堆注解建议使用jpa, 不过好像使用xml可以解决jpa注解的问题