落地DDD需要应对的挑战

DDD分层架构

DDD落地面临的挑战

前言:

DDD分层的目的是为了将技术复杂度和业务复杂度分离,让领域层负责业务复杂度,让应用层和基础设施层负责技术复杂度。

应用层的挑战:

  • 应用层需要解决的技术问题:控制整个请求的处理流程,包括调用领域层来执行业务活动,同时也需要处理好并发、幂等、事务等技术问题。

  • 方案:使用责任链的设计模式来应对挑战,责任链模式的优点:可以非常灵活地对处理过程进行拆分,比如可以将参数校验、幂等处理、事务处理、并发控制等拆分到独立的模块里,这些模块很容易被抽取为通用的模块进行复用,同时也实现了这些技术能力的可拔插性,大大降低了代码的复杂度。

领域层的挑战:

如何创建好的聚合?

设计小聚合:
  • 大部分的聚合都可以只包含根实体(Aggregate Root),而无需包含其他实体。

  • 即使一定要包含,可以考虑将其创建为值对象。

  • 聚合根大小的考虑:

    • 聚合根大点有利于逻辑的内聚,但是可能存在性能问题。

    • 聚合根小点可以解决性能问题,但是可能导致逻辑分散。

通过唯一标识来引用其他聚合或实体:
  • 当存在对象之间的关联时,建议引用其唯一标识而非引用其整体对象,或将需要的属性构造值对象。

  • 边界内的内容具有一致性:如果你发现边界内很难接受强一致,不管是出于性能或产品需求的考虑,应该考虑剥离出独立的聚合,采用最终一致的方式。

  • 常见场景:一个主记录对应多条明细记录的场景,方案如下:

    • 若可以有效控制明细数量,且明细数量较小时:主记录和明细记录可以设计为一个聚合。

    • 若明细数量可能很大时:考虑到性能的问题,我们应该将主记录和明细记录设计为两个聚合,当明细记录更新后发布领域事件,主记录根据明细更新事件做出相应的修改,这样就可以保证主记录和明细记录之间互不依赖。

基础设施层中Repository的挑战:

  • 过依赖倒置实现各层对基础资源的解耦:

    • Repository分为两部分:仓储接口和仓储实现。仓储接口放在领域层中,仓储实现放在基础层。

  • Repository的实现一般需要具备以下特性,以便解放领域层和应用层的复杂性:

    • 保证entity的唯一性

    • 支持缓存读写:将entity的唯一标识作为key,在本地对entity进行缓存。

      • 缓存读:提高读的性能。

      • 缓存写:用来支持延迟更新

    • 支持延迟更新

      • 每次操作都直接去更新数据库存在的问题:请求耗时增加、数据库压力倍增。

        • eg:一个请求要批量更新多个实体的信息,如果每个实体信息修改后都立即去更新数据库,那么每次请求都会对应着大量的数据库写操作,这样不但会导致请求的耗时显著增加,同时也给数据带来了巨大的压力。

      • 方案:采用unit of work的设计模式,将所有的DB写操作都先缓存起来,最后一并进行更新。

    • 并发控制:多个请求对一个实体进行操作,如果解决并发问题?

      • 通过版本号来实现,在实体中添加版本号字段,更新时判断当前实体的版本号和DB中的版本号是否一致,一致则更新,否则抛异常。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值