领域驱动设计-原理心得篇

本文详细介绍了领域驱动设计(DDD)的核心概念,包括通用语言、领域专家、贫血症与失忆症、领域、子域和限界上下文、架构、实体、值对象、聚合、领域服务、领域事件、资源库以及防腐层。DDD强调业务架构与技术架构的融合,通过建立通用语言减少沟通成本,避免业务变化带来的系统重构困难。文章还探讨了DDD在微服务架构中的作用,指出DDD可以弥补微服务在应对复杂业务变化时的不足,提供更灵活的业务模型设计。此外,文章通过实例解析了DDD中的关键概念,如聚合、领域服务和资源库,帮助读者理解DDD的实践应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

“最初我给本文起的标题是《领域驱动设计-理论入门篇》,但是文中掺杂了太多的个人理解,入门篇就显得太官方了,为了避免错误的理解把读者带偏,所以改成《领域驱动设计-理论心得篇》,期待你能发现其中的错误,并可以一同探讨。文章发布前邀请了拥有丰富领域驱动设计实战经验的大佬校正,所以我有理由相信,这篇文章一定可以给你带来一些有用的入门指导建议”

 

01 写在前面

    领域驱动设计(Domain-Driven Design,DDD)是一个有关软件开发的方法论,他提出基于领域开发的开发模式,基于DDD理论,我们可以设计出高质量的软件模型。

    这是一篇关于DDD理论大于实践的文章,其中会掺杂一些必要的代码用例,但通常都是伪代码。通常来说,理论介绍往往是枯燥的,所以我假象你对DDD是有兴趣的,这样才能趋势你耐心读完本文。我试图用言简意赅的句子解释清楚其中涉及到的各个概念,但是我不确定我理解的意思和我表达的意思是否符合你的口味,所以如果你在阅读过程中发现有什么地方我没有说清楚,我非常欢迎你能够联系到我进行探讨,你可以从公众号下方菜单处看到我的联系方式。

    初次接触DDD是20年8月份,因为换工作之后的项目需要,在飞哥(我的职场导师)的引领下慢慢进入了DDD世界。在我看来,业务很单一的项目是没有必要使用DDD的,如果一个纯CRUD(创建:Create,读取:Read,更新:Update,删除:Delete) 就能搞定的项目被要求使用DDD开发,就是在搞事情,这大概率会加重团队的负担,但是这不意味着DDD在简单项目里没有用武之地。DDD是一个方法论,你需要掌握他然后拆解成若干模型,在合适的地方使用合适的模型,就像你把飞机的刹车原理应用在你的小汽车制动上,这有何不可!

 

02 为什么使用DDD

    2004年,Eric Evans 发表《Domain-Driven Design –Tackling Complexity in the Heart of Software》,中文译为《领域驱动设计》,强调业务架构和技术架构的高度映射统一,提出并强化了业务领域、战略建模、限界上下文、防腐层等诸多新兴概念,DDD理念赋予技术架构必要的灵活性使之足以跟上业务的变化节奏,从此,DDD进入群众的视野。但在当时,在单体应用盛行的年代,DDD在单一的业务场景和快速开始快速开发快速上线的需求面前显得十分鸡肋,因此DDD理念带来的“额外工作量”导致其始终未能占领较大市场。

    而后,随着业务场景的日渐复杂庞大,开发、部署、维护简单的单体架构带来的迭代难、重构难、合作难等弊端不再被容忍,于是服务化概念被提出并盛行一时,直到2014年,伴随着容器化技术的成熟以及DevOps文化的兴起,由服务化概念进一步升华的微服务概念以及微服务架构被推崇并一度成为软件开发领域不可或缺的最佳实践。微服务架构极力追求业务层面的解耦和重用,以业务为导向进行服务划分,技术架构上要求做到高内聚低耦合,同时解决单体应用上出现的多团队协作难以及牵一发而动全身等诸多问题。微服务的出现和日渐成熟,仿佛成为了复杂业务开发实践上的银弹,似乎不懂微服务的开发已然是一个不合格的开发。可实际上是这样吗,微服务解决了诸多难题,就没有副作用吗?

    微服务的思想使复杂业务系统得到合理的拆分,分而治之解决了多团队合作困难问题,RPC(Remote Procedure Call 远程服务调用)拉通了不同语言开发之间的屏障。但是在应对多变的业务或者拆分出来的服务领域比较庞大时上始终提不上劲,甚至病情有所恶化。业务需求的变化带来的是各个服务之间的相互猜忌,相关人员往往要花更多的时间定位哪些服务需要作出响应,这还没完,实践中往往还会发生服务间相互推诿的情况,在已经“稳定”的代码上响应业务的变更,这是对代码动刀子的活,各团队人员在主观臆测谁应该动多一点谁应该动少一点时,往往得不到一个大家都满意的结论。哪怕最终问题被解决了,因为开发同学已经搞不清楚影响范围,在测试同学介入时往往也是抓耳挠腮。而对于最后即将上线的程序,开发人员还不得不小心翼翼的给各个请求加上各种“开关”以应对源自上下游服务的不信任,同时依然要为那些依赖服务不定时的变更而感到惶恐。甚至不幸的是如果你服务拆分之后的领域依然很庞大,那可能系统之间的耦合问题被解决了但是系统内如何应对如此庞大的领域业务?类似这样关于业务需求变更以及拆分后的服务依然庞大带来的问题,微服务思想并没有提供有效的指导建议。

    我通常把业务需求的变更分为两类,一类是系统类变更,另一类是非系统类变更,非系统类变更就比如支付功能需要用户的点击操作,这个操作属于业务范畴,但是又不是系统控制的。而系统类变更,最终体现在系统内部功能的变更上,而微服务思想并未在服务功能的拆分和治理上提出有效的建议,换句话说,微服务关注的点是服务级别的,很好的阐述了各个服务各个应用之间的依赖关系以及提出了很好的治理方案,但在服务之下,不同功能之间的协作关系却缺乏较好的指导建议。

    DDD正好可以弥补这个短板!当然,DDD与微服务的关系绝对不只是弥补短板这么简单,DDD理念使业务架构和技术架构达到高程度的契合,倡导结合各类优秀合适的“模式”(比如设计模式)进行开发,同时将设计重心放在复杂领域的划分上,这使得一向冰冷的技术架构能够灵活地应对业务的变化,特别是当今时代想找到一个不怎么变化的业务实在太难。

    需要解释的是,我并没有说DDD本身能够解决业务多变导致的所有问题,DDD只是方法而不是手段,他提出的适配器结合防腐层概念可以一定程度降低外部系统业务变更导致的代码变更而带来的影响,但模式才是真正能够解决本身业务多变的功臣。合适的模式与领域相结合,这便是DDD对于应对多变业务的指导建议。当然,不要指望存在一个系统可以设计之初就兼容未来所有的业务变化,业务变化一定会带来系统的变更甚至架构的变更,我们能做的只是降低变更带来的风险以及重构需要的成本。

 

03 什么是DDD

    DDD作为一个有关软件开发的方法论,他提出基于领域开发的开发模式,基于DDD理论,我们可以设计出高质量的软件模型。所有的DDD实践都需要围绕着其方法论而展开,这意味着DDD不像是某些技术框架即使不懂原理也能根据经验把碗端稳,了解其理论知识(观点)是步入DDD殿堂的第一步。

    同DDD所倡导的建立通用语言一样,我现在试图和各位对某些“术语”的理解上达成一致,注意,要完全理解和掌握这些术语可能不是一件容易的事情,甚至会很枯燥。但是这没关系,术语只是基于DDD开发的开胃菜,你大可以只是先掌握他们的基本概念,在真正决定动手的时候再详细了解。从知,到知其然,再到知其所以然!

 

04 通用语言

    通用语言是DDD最基础概念之一,可以从字面意思上解释。通用语言的目的是在业务语言和技术语言之间建立一个良好的映射关系,一个项目的开展通常包含多中利益相关方:业务、产品、项管、项目leader、开发leader、开发、测试等,通用语言的建立就是为了在项目的开展过程中,项目所包含的所有相关人员在针对同一个术语进行理解的时候保持统一,这个工作必须在项目开始前就做好(当然,项目开展过程中如果发现某个通用语言设计不合理也务必修改并同步所有相关人员),这将在项目行进过程中为我们降低相当大的沟通成本,以及在代码开发过程中开发人员可以花更少的时间去思考某个领域的概念或者方法字段的命名。

    比如:业务语言是“删除某模板的时候校验该模板是否有效,且删除成功之后,需要发短信给相关负责人”;从技术的角度来看,删除、校验、发送短信是动作,模板和相关负责人是资源,删除成功是事件,技术语言就是某动作操作了某资源然后发布某事件。如此看来业务语言和技术语言是不一样的,正因为如此,通用语言才显得至关重要。

    再比如:“素材”这个术语,在知识库领域里,素材通常表示一系列图片或者富文本,但是在PS领域,素材则表示其他的可以帮助构成整个PS作品的某个单一的元素。这需要在通用语言约定时说清楚,以防止某个精通PS的同学听到我说素材的时候不自觉地联想到笔刷或者矢量楼房等别的领域的东西。

 

05 领域专家

    在后面的内容中,你可能会偶尔看到“领域专家”这个字眼,领域专家并不是一个职位,他表示的是任何一个精通业务的人,相比于软件设计者和开发者࿰

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值