V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
asanelder
V2EX  ›  程序员

DDD 中的聚合根持久化问题(使用关系型数据库)

  •  
  •   asanelder · 2020-12-01 19:38:37 +08:00 · 3043 次点击
    这是一个创建于 573 天前的主题,其中的信息可能已经有所发展或是发生改变。
    老铁们,好像这种关系型数据库之间表的关系无法完美匹配领域模型啊!

    你们在使用关系型数据库时怎么持久化聚合根的?

    有没有好的思路和实践?
    31 条回复    2020-12-02 21:45:25 +08:00
    xuanbg
        1
    xuanbg  
       2020-12-01 19:41:57 +08:00
    不是你的数据模型设计错了,就是你的领域模型设计错了……
    xiangwan
        2
    xiangwan  
       2020-12-01 19:46:58 +08:00 via Android
    了解下领域模型和数据模型解耦合
    asanelder
        3
    asanelder  
    OP
       2020-12-01 19:58:47 +08:00
    @xiangwan #2 有没有好的文章,铁子,找了半天没找到。。。
    @xuanbg #1 感觉都没错啊。。网上说的最好的方式是使用 mongodb 。。。
    xiangwan
        4
    xiangwan  
       2020-12-01 20:56:17 +08:00 via Android
    领悟模型有人也叫成业务模型,对象模型,可以换着搜搜
    有个解藕思路是,在仓储层转换领域对象和数据对象
    主要是转换下思维,不执意让数据表和领域模型完全对应。可以像上面提到的,在数据访问层进行转换
    asanelder
        5
    asanelder  
    OP
       2020-12-01 21:34:52 +08:00
    @xiangwan #4 俺用的 spring data jpa,也是想在数据访问层做做文章。

    之前没用过 jpa 和 ddd,俺也在摸索中。。。

    谢谢铁子给的思路,俺慢慢尝试。
    CoderGeek
        6
    CoderGeek  
       2020-12-01 21:43:25 +08:00
    我最近也在搞 ddd 费劲
    xiangwan
        7
    xiangwan  
       2020-12-01 22:07:06 +08:00 via Android
    @asanelder 不客气

    @CoderGeek 准备放弃 ddd 了。
    最近觉着 ddd 倾向把问题复杂化,不敏捷。
    imherer
        8
    imherer  
       2020-12-01 22:08:58 +08:00
    @CoderGeek
    @xiangwan

    搞了 2 个多星期的 DDD,一开始很不习惯,弄下来之后发现还是挺爽的
    CoderGeek
        9
    CoderGeek  
       2020-12-02 00:45:48 +08:00
    我最近也在搞 ddd 费劲
    @xiangwan
    真的需要业务专家 不是说技术的问题,
    起码第一步不能画跑偏了
    xiangwan
        10
    xiangwan  
       2020-12-02 02:12:44 +08:00 via Android
    @CoderGeek ddd 有很多优点,但是在技术层面,“原教旨“ddd 用的方式很复杂,例如:事件溯源,命令查询分离;
    “聚合根“也是一个好坏参半的解决方案,除了本贴持久化的问题,还面临选择是用充血模型还是贫血模型,大部分贫血模型的项目其实都是伪 ddd 。

    @imherer 我尝试好多次 ddd 了,总感觉不够 ddd 。它的“战略工具”确实可以,前阵跟着微服务有火了一把
    imherer
        11
    imherer  
       2020-12-02 09:06:34 +08:00
    @xiangwan 战略工具 具体指什么 有相关文章或者 demo 吗?
    huifer
        12
    huifer  
       2020-12-02 09:22:39 +08:00
    聚合根是否需要落地是个问题. 有些可能是联合查询对外暴露, 聚合根落地的话简单的形式就是各个外键 id 存储
    asanelder
        13
    asanelder  
    OP
       2020-12-02 09:53:45 +08:00
    @xiangwan #10 确实,完全遵循原教旨很麻烦,但俺也是从中借鉴一些思想,比如领域模型,充血对象等等。

    之所以想实践 DDD,就是感觉之前做的所有 Web 无关是 CRUD,实在是受不鸟啦!
    @huifer #12 俺在使用 spring data jpa 做持久化,持续摸索中。。。
    CoderGeek
        14
    CoderGeek  
       2020-12-02 09:58:24 +08:00
    @xiangwan 我的想法是没有所谓绝对标准,不管什么架构模式都是一步步沉淀的 还是得明白业务领域,不说写什么的问题,起码前期梳理的全面 大模块不会跑偏, 这个东西确实需要有一定沉淀的业务人员和技术人员 要么连好事都算不上 浪费时间
    CoderGeek
        15
    CoderGeek  
       2020-12-02 10:03:24 +08:00
    @imherer
    @xiangwan
    取其精华,去其糟粕 ;有好有坏
    leoskey
        16
    leoskey  
       2020-12-02 10:10:51 +08:00
    我是参考 https://www.cnblogs.com/uoyo/p/12167224.html 的实践,有些落地难得地方需要妥协
    iamppz
        17
    iamppz  
       2020-12-02 10:16:23 +08:00
    聚合根和数据库对象之间通过 Converter 来 serialize 和 deserialize
    asanelder
        18
    asanelder  
    OP
       2020-12-02 11:33:06 +08:00
    @leoskey #16 感谢,俺看看

    @iamppz #17 确实是一个方法,但俺想利用 ORM 直接将数据库对象映射到聚合根,多做一次转换好麻烦啊
    asanelder
        19
    asanelder  
    OP
       2020-12-02 11:36:45 +08:00
    @xiangwan #4
    @iamppz #17

    其实这种从领域对象到数据对象的转换就是因为关系型数据库中的数据模型无法完全匹配领域模型,而俺看 mongodb 的文档可以完全匹配,那么,是不是换成 mongodb 就没这种烦恼了呀
    hantsy
        20
    hantsy  
       2020-12-02 13:31:12 +08:00
    技术上使用 Spring Data 的话,它已经抽象了 DomainEvent,AggregrateRoot 处理,适用大多数 Spring Data 子项目,包括 Spring Data JPA, 请参考 Spring Data 文档。
    https://docs.spring.io/spring-data/data-commons/docs/current/api/org/springframework/data/domain/DomainEvents.html
    https://docs.spring.io/spring-data/data-commons/docs/current/api/org/springframework/data/domain/AbstractAggregateRoot.html


    另外代码层面实现上,充分利用 Spring 特性,比如 ApplicationEvent 处理 Domain Event,Message Broker 来实现跨 Domain (不同的 BoundedContext )数据同步。

    Domain 建模,Aggregate Root 的颗粒度源于实践,怎么具体处理,取决你的长期经验。经验需要不断积累,不断试错和踩坑,技术架构也是需要不断演进的。理论上很多东西一看就明白,落地很难,比如 Single Reponsibility 拿到国内,细化接口规范后,有些人就只会比较字符数量,便得出结论是增加了任务量。
    hantsy
        21
    hantsy  
       2020-12-02 13:38:51 +08:00
    hantsy
        22
    hantsy  
       2020-12-02 13:42:34 +08:00
    kvkboy
        23
    kvkboy  
       2020-12-02 13:44:01 +08:00
    kvkboy
        24
    kvkboy  
       2020-12-02 13:45:06 +08:00
    @kvkboy 手快不小心不小心发出去了,可以看看这个文章,挺有参考的价值。不过更多的还是需要看书,ddd 经典的两本一本理论一本落地
    hantsy
        25
    hantsy  
       2020-12-02 14:28:16 +08:00
    @kvkboy 六边形和洋葱不错,特别六边形,把系统进出接口进行隔离,感观比较清晰。

    文章提到的 Cargo 例子作为 Eric 原书 DDD 的一部分,使用了 Spring 框架,现在已经有各种版本了。

    Eclipse EE4J 官方也维护了一个基于 Java EE/Jakarta EE 规范的 Cargotraker.

    https://github.com/eclipse-ee4j/cargotracker
    hantsy
        26
    hantsy  
       2020-12-02 14:30:19 +08:00
    asanelder
        27
    asanelder  
    OP
       2020-12-02 18:32:22 +08:00
    @hantsy #20
    @kvkboy #23

    感谢二位铁子,文章俺都看了,也有一些思路了,正在实践中。。。
    Kirsk
        28
    Kirsk  
       2020-12-02 19:06:32 +08:00 via Android
    Ddd 是业务建模 不是数据建模 不懂业务还是不要玩
    iamppz
        29
    iamppz  
       2020-12-02 20:13:14 +08:00
    @asanelder 个人感觉跟数据库没有关系,你需要一个合适的 ORM,我用的 Spring Data JPA
    hantsy
        30
    hantsy  
       2020-12-02 20:43:24 +08:00
    @iamppz 理想的设计层面,Domain 建模不会考虑到数据库,到真正实现的时候才考虑。如果 Domain 模型与数据库有关系,就是 DDD 中的 Entity,最终要持久化,不得不考虑到数据库的问题。

    国内的实践,直到现在很多人做项目或者产品还是本末倒置,需求一到,数据库 Schema 优先设计,使用一些工具自动生成 Entities (或者什么框架需要的类似的东西,这只是数据库的 Entities,与 Domain Model 中 Entities 无关)。从一开始就是面向数据库的,最终业务都是围绕数据存储。以前项目中经常遇到有谈业务的时候,没两句直接会想到数据库存放,页面一个搜索框,能够联想到联合查询等,完全脱离不了数据库思维。
    asanelder
        31
    asanelder  
    OP
       2020-12-02 21:45:25 +08:00
    @iamppz #29

    俺就是用的 spring data jpa,但是也只是做 orm, m 和 domain object 还是要人工转化一下。

    @hantsy #30

    今天搞定 domain object 和 data object 的转化后,用充血模型写业务,有点爽啊~~~
    关于   ·   帮助文档   ·   API   ·   FAQ   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   4144 人在线   最高记录 5497   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 31ms · UTC 07:13 · PVG 15:13 · LAX 00:13 · JFK 03:13
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.