09|分层架构:怎样逃离“大泥球”?
钟敬
你好,我是钟敬。
上节课,我们完成了数据库设计,解决的是怎样保证数据库和领域模型一致的问题。接下来,我们来解决怎样保证代码与模型一致的问题。
这个问题又分成两个层面。第一个层面是要有一个合理的代码架构,第二个层面是更详细的代码编写。今天我们主要解决第一个层面的问题,通过引入 DDD 的分层架构,建立代码的骨架。
我们这节课的方法综合了《领域驱动设计:软件核心复杂性应对之道》(后面简称《DDD》)这本书里的内容以及“六边形架构”的思想。六边形架构是由敏捷软件开发专家 Cockburn 提出的,用来分离技术和非技术关注点。如果你只是想掌握分层架构的最佳实践,那么学习这门课就可以了;如果还想进一步了解六边形架构的来龙去脉,可以读一下作者本人的文章。
那么,我们为什么要采用分层架构呢?原因就是为了避免“大泥球”式的代码。
源代码仓库地址
逃离“大泥球”
我们知道,系统中的代码都有各自的目的,有些处理领域逻辑,有些处理用户界面,有些处理数据库的访问……这些代码的关注点各不相同。但在很多开发团队中,并没有明确的手段来分离代码的关注点,从而使不同关注点的代码混在一起,这样就会造成下面几个问题。
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
- 深入了解
- 翻译
- 解释
- 总结
本文介绍了如何通过引入领域驱动设计(DDD)的分层架构来解决代码与模型一致性的问题。作者首先指出了代码混乱的问题,难以维护和存在质量问题。然后详细介绍了分层架构的设计原则和结构,包括分离领域层、建立应用层和适配器层等。在分层架构中,领域层负责封装领域数据和逻辑,应用层负责调用和协调领域层逻辑,而适配器层则处理输入输出技术,将业务功能适配到不同的输入输出技术。通过这种分层架构,可以有效避免“大泥球”问题,提高代码的可维护性和一致性。文章还介绍了仓库模式和分层架构的权衡,以及引入common层用于存放工具和框架。最后,强调了在实践中进行权衡,找到适合自己项目的架构。整体而言,本文通过具体的示意图和代码结构,清晰地阐述了分层架构的设计思想和实践方法,对于需要了解和应用分层架构的开发人员具有一定的参考价值。
仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《手把手教你落地 DDD》,新⼈⾸单¥59
《手把手教你落地 DDD》,新⼈⾸单¥59
立即购买
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
登录 后留言
全部留言(33)
- 最新
- 精选
- escray置顶分层架构的代码框架看上去不错,不知道后面有没有实际项目的代码示例,show me code。 domain application adapter( driven < restful / web > / driving < persistence > ) common( framework / util ) 代码的分层是应该在一开始就按照领域模型来分 domain, application, adapter( driven < restful / web > / driving < persistence > ), common,并且填充不同的类型(对象);还是按照业务用例,逐步推进? 我觉的比较好的办法,可能是先建立框架,然后再按照用例逐步递增。 在分层结构变化表里面,提到了应用层和被动适配层的合并,或者应用层和主动适配层的合并,那么是不是有可能应用层和适配层合并起来呢? 对于课后题, 1. 其他的适配器,没有出来,后来看留言提示,知道有消息队列和定时任务调用 2. 同样没能想出来,主要是我之前觉得领域层依赖持久化层做数据持久化很自然。 没有想到 DDD 居然会直接指导代码的目录结构。 照抄了一份放在 github 上: https://github.com/escray/geektime/tree/master/DDD-hand-in-hand
作者回复: 分层架构,可以先把大的包结构定下来,然后逐步往里填内容。动手实践很棒👍🏻
2023-02-06归属地:北京2 - leesper思考题: 1. 跟输入输出具体技术有关的都算,那么命令行界面的访问(CLI)、消息队列服务、缓存服务这些的,都算适配器 2. 内层依赖外层,我记得徐昊老师的课上提了一嘴,问题出在持久化层上,领域层依赖持久化层进行数据持久化,这就变成了内层依赖外层。方法就是“依赖倒置”原则,让领域层依赖于抽象的Repository,然后把真正的实现细节放到持久化层,这样只要接口不发生变化,实现怎么变都可以。这就叫“高层接口不依赖于底层接口,二者都应该依赖于抽象;细节依赖于抽象,而抽象不依赖于细节”。
作者回复: 两个问题都回答的挺到位 👍🏻
2022-12-31归属地:广东17 - zcc问题1:常见的还有MQ消息的订阅与发送 问题2:应该是主动适配器层会破坏依赖原则
作者回复: 非常棒
2022-12-25归属地:广东35 - Geek_1e04e7问题2:领域层会依赖持久化层,能想到的方法是将持久化相关的接口抽象定义放在领域层保持稳定。就不会破坏关系。
作者回复: 没错
2022-12-26归属地:广东4 - Michael问题2. 领域层依赖持久化层做数据持久化?
作者回复: 是的👍🏻
2022-12-24归属地:广东54 - Jaising继续第四篇两千字笔记《分离关注点构建领域核心——领域驱动设计中的分层架构》: 领域驱动设计中分层架构与六边形架构结合的最大魅力是保持了领域模型作为核心的稳定性,核心思想是分离关注点,设计原则是依赖倒置,从而使得不依赖用户交互与持久化机制的领域模型独立演进成为可能 https://juejin.cn/post/7188700862955388987
作者回复: 总结得很好。继续点赞收藏转发 :)
2023-01-17归属地:浙江3 - 6点无痛早起学习的和尚1. 这里尝试理解了 DDD 的分层架构和目前比较大众的开发模式的关系,麻烦看看是否理解有偏差 2. 领域层对应实体,领域层里面的逻辑处理是把以前的 Service 层的逻辑封装到了实体里,这里应该就是后面要讲的“贫血”&“充血”对比 3. 应用层对应以前的 Service 层,但是又有区别就在于,是把领域层的逻辑进行组装形成的逻辑,以前的 Service 层是直接硬写逻辑 4. 适配器层这个就很好理解了,被动就是以前的 Controller 层等等,主动就是对 DB、Redis的操作封装类。 5. 所以关键点区别就在于领域层的设计
作者回复: 没毛病 👍🏻
2023-01-04归属地:广东3 - Breakthrough老师,领域驱动设计最终交付给开发同学的输出物应该是什么是前面画的类图和这个分层架构吗
作者回复: 领域模型(类图) 业务规则表 词汇表 设计模型(包括分层架构)(可选) 代码
2023-07-26归属地:北京2 - RED_Allen_Account1.常用的适配器还有MQ和定时任务 2.在domain和repository之间会破坏层间依赖,一般在domain层中加入gateway的概念,使用DIP反转domain和repository的依赖关系
作者回复: 嗯,没错
2023-02-11归属地:上海2 - 赵晏龙针对数据流入流出的途径,抽象为Driven/Driving,这很Impressive,好像从来没有做过这方面的思考
作者回复: 我当初学六边形架构的时候,也有同感。
2022-12-31归属地:广东2
收起评论