DDD - 来自听众的16个DDD问题,美团技术团队是这样回答的

简介: DDD - 来自听众的16个DDD问题,美团技术团队是这样回答的

DDD的框架和组织管理

1. 如何从代码框架上约束CQRS经领域模型走仓储和规约,不要在应用层上同级别互调用。跨过领域自己在应用层写实现,读时不要应用走缓存和API请求,这些没有框架的硬件约束很难管控程序员的配合。如果纯粹靠行政又很奇葩,还是有一套体系+团队结构配合。

领域驱动设计的目的是为了帮我们解决复杂业务的分析,架构和代码落地问题。虽然理论上可以建立架构规范进行编码约束,如引入Sonar规则扫描来规范代码的架构分层和调用依赖,但部分场景下一些简单的需求也遵循从仓储-领域-应用-接口这种分层,会比较重。我们团队的实践是有一定复杂度的业务要沉淀领域模型,但对于一些简单的场景,如后端日志,简单的配置数据管理,省略领域层未尝不可。

毕竟采用领域驱动设计是为了帮我们解决问题,而不是在简单问题上强制某种规范来限制我们。

2. 有没有一套通用的DDD 落地框架?

目前还没见到过,DDD都是要结合业务上下文进行实践的,是方法而不是工具。所谓方法是需要结合实际场景来使用的,而工具往往解决特定问题,可以直接使用。

3. 如何驱动专家们参与到领域设计流程?

人人都是领域专家,最重要的是对业务认知达成共识。可以技术主导来进行概念抽取,把描述业务的词汇进行沉淀和统一管理,有意识的在沟通中使用这些词汇描述业务,如产品文档、技术文档和面向业务的培训资料等,逐渐落地。

4. DDD团队实践分享,如何在组内推广落地实施?

从统一语言做起,尝试用统一语言来描述我们的业务需求。

DDD如何在老系统上使用或者迁移

5. 快速业务迭代压力下,老项目如何快速转变思维和方式,带来的时间成本影响怎么测算?

领域驱动设计是一种将复杂业务抽象为系统模型的方法,没有额外的成本,任何时候都可以开始。但的确会有思维方式上的转变,可以循序渐进,先从统一语言做起。

6. DDD如何以最小代价应用在历史系统上?

DDD是一个帮我们进行业务分析,将业务映射为模型的方法,使用它没有额外的代价,它会帮助我们构建描述业务的概念体系,建立起更加合理的领域模型,至于是否要重构历史系统,在代码层面实现领域模型,完全是一种项目抉择,哪怕不重构系统,它在分析业务,抽象模型上的价值依然存在。

DDD的落地实践细节

7. 接口返回给前端的是领域对象Domain还是根据前端页面定义的VO?操作数据返回的是Entity,数据转换用的DTO,返回前端是VO,Domain什么时候用?VO\Entity\DTO\Domain具体是怎么用的?

不同公司的代码规范里按架构分层定义了PO,BO,VO,DTO等很多概念,这些概念都承载了特定团队在编码上的一些规范。

首先,不要被这些概念所束缚,而是针对自己的项目,确定适合自己的规范是什么;

其次,再来看哪些O是可以拿来参考和使用的,比如DTO,Entity是简单对象只有数据而无行为,仅用于传输数据(对外交互用DTO,访问数据库通常用Entity),其他的O是不是真的有必要做那么精细的区分值得商榷。

我们团队采用的是贫血模型,虽然用BO来处理Domain层的实体,但也仅仅是个简单的对象,并不包含行为方法,与Entity相差不大,如果实体和表结构相同,就复用Entity(这种复用是有代价的,未来当Entity与领域模型不能一一对应时,需要重构)

8. 事务是怎么处理的?数据新增更新落库是怎么处理的?事件溯源是怎么实现的?联表查询时数据转换怎么处理?

原则上事务在应用层处理,数据更新,查询这种都在仓储层处理,联表查询能避免就避免,不能避免的要仔细评估必要性(Base Table + Extension Table这种反映类继承关系的数据模型可以接受联表查询)。

在仓储层对跨多个表的聚合根进行组装。

9. 聚合遇到审批流该如何划分?聚合的CURD如何处理?DDD一般开发套路是什么?DDD有推荐学习的网站吗?有没有复杂业务用DDD实现的开源项目推荐?

实体的状态变化最终要提交到数据库(CRUD),如果是充血模型,可以通过插件生成动态SQL,在仓储层对实体提交进行封装。但我们的实践并没有完全采用这种模式,部分实体状态的更新是直接更新到具体字段的,这样在代码上比较直白和明确。

推荐DDD的两本经典书《实现领域驱动设计》,《领域驱动设计 软件核心复杂性应对之道》,另外领域驱动设计属于方法范畴,避免拿来主义,生搬硬套,而要结合业务和系统实际情况进行应用。

10. 落地实现的方式,是在领域服务层做业务编排还是聚合根做业务编排?

不管是聚合根还是领域服务,其核心职责是封装,封装的目的是复用;

领域服务与聚合根的差异:领域服务主要处理哪些不适合放在聚合根里的逻辑,例如:活动,规则,人群,通过三个实体(聚合根)实现,当规则发生修改时,如果要变更活动状态,此时可以在领域服务里分别操作规则和活动两个实体。

应用层的职责是编排,编排的目的是灵活组装领域层的能力应对流程变化,解决不同场景下的流程差异问题。

有时候这里面的边界很模糊,需要依据具体情况来取舍。

11. 领域模型的分离,如何确定领域模型更准确?

领域驱动设计最根本的是要关注业务,对业务进行抽象,在用户,产品,技术之间达成共识,这种共识本质上就是领域知识,然后基于这个领域知识来设计系统,将其线上化。

验证领域模型的常用方法是场景走查,通过业务发展趋势来确定未来可能出现的场景,来验证当前模型是否具备扩展性。

12. 实战型的DDD代码到底如何写呢?DDD带来的问题是什么?

更多的用DDD来抽象模型,在代码实现上并没有去追求一个完美的充血模型,但未来会进行这块的探索。在spring单例模式下构建充血模型有一定的理解成本,学习曲线比较陡峭。

DDD带来的最大问题是容易陷入DDD本身的概念体系而跳不出来,反而被这些概念束缚和折磨。这不是DDD的问题,而是我们使用的姿势不对。

13. 遗留代码如何分节奏落地DDD?

先看有无必要,如果需要基于遗留代码来迭代新的业务能力,可以结合遗留代码的业务功能和新的需求来尝试进行抽象。第一步先统一语言,遗留系统解决什么问题,涉及哪些业务概念,新需求解决什么问题,涉及哪些业务概念,尝试进行抽取和统一;接着,这些概念进行进一步细化分析,确定概念的构成与分类,构建类层次;在落地代码时,适时进行代码重构,让新老代码反映这些概念。

其它

14. DDD和微服务的关系,以及落地的方法。

个人理解DDD和微服务是互相成就的关系,2004年Eric Evans在《领域驱动设计》中首次提出了DDD的概念,提出之后并未得到很好地推广,直到2014年Martin Fowler在《Microservices》提到微服务之后,DDD才真正开始发挥它的价值。主要是因为微服务架构虽然得到了大家的认可,但对于如何划分微服务、该划分到什么粒度一直都没有很好的标准和答案,而DDD刚好为此提供了一套指导方法和指导思想。

DDD里面的限界上下文从业务视角来看,它是语言的边界和模型的边界,从技术视角来看,它也是应用的边界和技术的边界,所以我们可以从业务问题出发,分析领域模型,划分限界上下文,然后再从技术视角考虑质量属性、功能复用以及服务集成等一些技术因素对限界上下文做进一步识别,最后划分出来的限界上下文也会作为微服务划分的主要参考。

15. 想了解下DDD的经典实践,用走过的弯路。

分享一个走过的弯路:对内协作时称我们在搞领域驱动设计,沟通时言语中满是聚合根、实体、值对象、限界上下文、事件风暴等高级词汇,发现这不仅没有帮助到我们的工作,反而增加了聊天的难度。不妨抛开这些具体的招式,和产品与用户坐下来好好聊聊需求,需求中涉及到哪些业务概念,这些概念之间有什么关系,概念有哪些状态,关键属性是什么等等。

16. DDD一直都知道也在运用,知道最终整体目的,但落地实际优秀案例加代码结构的案例培训和参照的太少,建议尽量以简单代码块说清楚每个知识点的意义和愿景。

对于偏业务流程和数据操作的管理信息系统而言,按照DDD的概念体系来构建系统,在系统实现上采用完美的面向对象充血模型,并非DDD要追求的核心目标。我们的实践中更多的是通过DDD来帮助梳理业务,抽象合理的领域模型;落地上,依然采用了相对简单的贫血模型,未来可能会进行一些充血模型方面的探索。

本文摘自:@美团技术团队

相关文章
|
缓存 架构师 Java
架构师必备 - DDD之落地实践
今天带大家认识下DDD,一个听起来很垃圾却真的很牛X的设计思想,架构师必备!
|
Cloud Native 架构师 Devops
云原生时代领域驱动设计(DDD)的价值——从《没有银弹》说起
软件开发需要面对本质困难和附属困难。云原生、DevOps实践大幅降低了附属困难,使得架构师可以全力聚焦于业务复杂性,而DDD恰是管理业务复杂性的有效方法。
1590 0
云原生时代领域驱动设计(DDD)的价值——从《没有银弹》说起
|
3月前
|
缓存 架构师 中间件
成为工程师 - 如何做DDD领域驱动设计?
成为工程师 - 如何做DDD领域驱动设计?
|
5月前
|
敏捷开发 存储 前端开发
【美团技术】领域驱动设计DDD在B端营销系统的实践
【美团技术】领域驱动设计DDD在B端营销系统的实践
|
设计模式 架构师 程序员
DDD洋葱架构才是 yyds!阿里大牛手记(DDD)领域驱动设计应对之道
虽然身为架构师,设计一个高质量的架构依然是复杂与困难的。 简单来说,动用大量的资源只为了一套优质的三高架构并不正确,而是该在了解当前业务现状的情况下,创造出灵活、可维护、健硕能成长的。
|
架构师 算法 测试技术
小团队也能做DDD-中篇
小团队也能做DDD-中篇
231 0
|
Java 机器人 程序员
大白话DDD(DDD黑话终结者)
大白话DDD(DDD黑话终结者)
360 0
|
消息中间件 运维 前端开发
DDD实战之六:战略设计之技术决策
DDD实战之六:战略设计之技术决策
DDD实战之六:战略设计之技术决策
|
持续交付
《持续交付背后的故事:重构性格成为优秀的叛逆者》电子版地址
持续交付背后的故事:重构性格成为优秀的叛逆者
112 0
《持续交付背后的故事:重构性格成为优秀的叛逆者》电子版地址