Loading [MathJax]/jax/input/TeX/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >可落地的DDD的(2)-为什么说MVC工程架构已经过时

可落地的DDD的(2)-为什么说MVC工程架构已经过时

作者头像
方丈的寺院
发布于 2019-08-05 09:43:49
发布于 2019-08-05 09:43:49
1.6K00
代码可运行
举报
文章被收录于专栏:方丈的寺院方丈的寺院
运行总次数:0
代码可运行

摘要

mvc是一种软件设计模式,最早由Trygve Reenskaug在1978年提出,他有效的解决了表示层,控制器层,逻辑层的代码混合在一起的问题,很好的做到了职责分离。但是在实际的编码实践过程中,你会发现这个模式随着业务的扩展,变的逻辑混乱,代码重合度很高。这里借鉴DDD思想提出一种新的工程结构。

mvc的问题

通常一个前后端分离的系统,后端工程系统结构图通常下面这样

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
1. 四层 controller/service/manager/mapper

  2. 不可以同级调用

  3. 上级可以知晓下级,下级不可知晓上级,也就是bean的转化放在上级

这个分层结构职责分离是按照纵向切分的

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
1. 资源服务层repository是面向DB编程

  2. service层是面向前端页面编程。

也就是说,对于某一块的业务,他没有将逻辑抽象到一起,他只是将一次request按照纵向切分了。没有进行横向的业务切分。 这样将会导致的问题职责分散,逻辑重复度高

  • bean的创建太随意,基本就是一个需求对应一些dto, vo,query bean
  • 不同开发者对于同一个领域的东西有不同的bean,同一个开发者对于相同逻辑的bean,过了几个月,又定义出一个差不多的bean

没有边界

  • 根本没有上下文/边界的概念,比如说店铺会和用户有交互,订单会和用户有交互,通常在DB存储时只会存关联id,然后需要去取对应的名称,其他属性信息。这些信息的获取,有些开发在manager层操作,然后将属性定义到了店铺相关的DTO中;有些放在了service层做。controller/service/manager各个层次都可以调用,没有任何约束。

mvc的演进

按照上述的说明,在一个单体服务中,随着业务的不断迭代,可能会发生什么严重的问题。

举几个真实鲜活的例子

分库分表的例子实体A是我们业务中的一个基础的重要的实体,对应的数据表tableA,一开始业务很简单,只有1个服务,在这个服务里面调用。后来业务扩张了,有十几个服务了,然后十几个服务直接查这个tableA。tableA也扩张成为了tableA,tableB,tableC。有些人觉得代码重复度高了,将mapper/manager层拆成共通的部分打成一个jar包,然后各个微服务中引入这个jar。业务变得更加复杂了,服务扩展到几十个了,tableA数据也有几千万了,这时候要做分库分表了,怎么整。

最后花了差不多1年,涉及十几个团队,才把这个mapper/manager调用改掉,然后做分库分表。

有人可能觉得这个只要在服务拆分时,避免直接调用就可以了,那再举个其他类型的例子。

用户等级的例子

用户的等级,用户的分级是很复杂的,不同的业务阶段有这个不同的定义。比如一开始定义一个字段叫grade的代表用户等级。 然后各个业务都在查这个表的字段grade进行判断,然后产品需要改了,增加了判断必须同时要达到什么条件才能称作等级x。这时候你又得满世界的改了。

DDD的工程架构

那如何运用DDD的思想进行改造呢核心思想:封装领域内的逻辑,统一对外暴露的入口,防止业务逻辑泄露。

  • 在mvc纵向切分的基础上,增加一层领域的横向切分
  • 同一个工程里面,领域之间的调用只能通过domainService,这样可以屏蔽领域内的数据库是如何持久化的,业务逻辑是如何判断的、算法是如何实现的。 service之间可以直接调用。
  • 领域内还是纵向切分,安装mvc分层结构。

上面的只是一个草图,我们真实的结构图比这要稍微复杂些。领域内会区分领域对象,领域服务,基础设施层。这样在领域内进行指责分离,不过从实际的执行过程中领域内的比较细节,执行起来ROI比较低,推荐大家可以先按这套执行。

画外音:估计有些程序员看到这个工程结构变化呵呵一笑,觉得没多大价值,没什么改变必要。

这种工程的结构划分从提出来的到真正被我们团队成员接受的时间周期差不多是8个月。 原因大概是这么几类

  1. 引入新的分层,太复杂了,增加了代码复杂度
  2. 我这块业务很简单,CRUD就行了,没涉及到服务之间的交互。直接mvc一条道走到黑就可以。

如果你看这篇文章也是这种感受,不妨花点时间看下你们业务的代码,看看重复度有多高,看看逻辑有多散乱。你就会明白。

DDD工程的演进

DDD工程的演进也就是服务的拆分了,放到下期讲。

总结

很多DDD的文章都在说传统的编程方式是面试数据库编程,导致对象中只有getter,setter,也就是贫血模型,贫血模型是没有业务逻辑,面向过程设计,不符合面向对象设计原则。

对于这个结论我是同意的,但是对于造成的原因不是很同意。个人认为造成这个原因的主要原因还是在于长期以来的MVC这种模式只有纵向切分导致。如果结合横向切分,有没有DDD也无所谓。这里再引用一下驱动方法不能改变任何事情这段话,如果你能深入理解职责、封装。并随着业务的迭代,不断的重构你的代码,那么你不需要什么DDD,或者其他方法论。

使用职责、封装和组合; 以接口的视角思考,即“人们如何使用我的组件?”; 使用相关技术写好代码,包括可读性、信息性、简洁、自描述,尽量避免显式地使用模式; 有能力回答特定业务的“本质”;“本质”是一个模型,但不意味着类和方法,它意味着回答问题“这个业务如何真正地工作?”

因为这些约束,都是强迫你去思考,去做职责的思考,去做模块的封装。如果你/你团队成员已经领会其中的道理并很好的运用,还需要这些条条框框干吗呢?

下一篇领域与微服务划分,欲知后事如何,请听下回分解。

相关阅读

可落地的DDD(1)-目标讨论

关注【方丈的寺院】,第一时间收到文章的更新,与方丈一起开始技术修行之路

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-05-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 方丈的寺院 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
DDD实战之二:看看代码结构长啥样
真正开始 DDD 旅程前,我想让您看到经过 DDD 设计之后的代码长啥样。我想,这是所有本着“talking is easy, show me your code”理念的程序员都比较在乎的观念。
张逸
2023/03/23
8920
DDD实战之二:看看代码结构长啥样
可落地的DDD(3)-如何利用DDD进行微服务的划分
前面两篇介绍了DDD的目标管理、DDD的工程结构调整。这篇讨论微服务的划分。微服务是目前后端比较流行的架构体系了,那么如何做好一个微服务的划分?一个微服务的粒度应该是多大呢?这篇主要介绍如何结合DDD进行领域划分。
方丈的寺院
2019/08/05
9270
可落地的DDD(3)-如何利用DDD进行微服务的划分
DDD落地之仓储
hello,everyone。又到了周末了,没有出去玩,继续肝。从评论与粉丝私下的联系来看,大家对于DDD架构的热情都比较高。但是因为抽象化的概念较多,因此理解上就很困难。
柏炎
2022/08/23
1.2K0
DDD落地之仓储
从单体架构迁移到 CQRS 后,我觉得 DDD 并不可怕
点击上方“芋道源码”,选择“设为星标” 管她前浪,还是后浪? 能浪的浪,才是好浪! 每天 10:33 更新文章,每天掉亿点点头发... 源码精品专栏 原创 | Java 2021 超神之路,很肝~ 中文详细注释的开源项目 RPC 框架 Dubbo 源码解析 网络应用框架 Netty 源码解析 消息中间件 RocketMQ 源码解析 数据库中间件 Sharding-JDBC 和 MyCAT 源码解析 作业调度中间件 Elastic-Job 源码解析 分布式事务中间件 TCC-Transaction
芋道源码
2022/08/29
9390
从单体架构迁移到 CQRS 后,我觉得 DDD 并不可怕
DDD 领域驱动设计:贫血模型、充血模型的深入解读!
要想深入掌握和了解 DDD 领域驱动设计的核心,那无论如何也绕不开两大较为抽象的概念——“贫血模型”、“充血模型”:
玄姐谈AGI
2021/02/12
10.6K1
DDD 领域驱动设计:贫血模型、充血模型的深入解读!
怎么说服领导,能让我用DDD架构?
我也苦思冥想,怎么跟领导说咱们从 MVC 升级到 DDD 吧,因为 DDD 代码结构更加清晰、领域驱动比测试驱动开发更加先进、研发的兄弟们也更想用用新框架等。
小傅哥
2022/03/28
6510
怎么说服领导,能让我用DDD架构?
对DDD(领域驱动设计)分层架构的理解(适合新人)
目前团队大多数项目都是基于DDD分层架构开发的,而不是传统的MVC模式,这就让很多之前没有接触过DDD思想的同学在刚开始接触项目的时候有点懵。那么什么DDD?这种DDD项目结构和之前的有哪些不同,我该如何开发我的代码,开发不同职责的代码该放在哪里?下面就我的理解,说一说DDD的分层架构。
架构之家
2022/09/27
2.2K0
对DDD(领域驱动设计)分层架构的理解(适合新人)
由Spring应用的瑕疵谈谈DDD的概念与应用(一)
多数有经验的程序开发者都应该听说过DDD,并且尝试过将其应用在自己的项目中。不知你是否遇到过这样的场景:你创建了一个资源库(Repository),但一段时间之后发现这个资源库和传统的DAO越来越像了,你开始反思自己的实现方式是正确的吗?或者,你创建了一个聚合,然后发现这个聚合是如此的庞大,它为什么引用了如此多的对象,难道又是我做错了吗?
aoho求索
2019/03/07
9270
可落地的DDD(6)-工程结构
几年前我在可落地的DDD的(2)-为什么说MVC工程架构已经过时总结了基于DDD的微服务工程结构是怎么样的。那篇文章重点阐述了与MVC架构的区别。导致一些细节没有讲清楚,本文结合最近两年的实践,再详细阐述下。
方丈的寺院
2022/11/08
4800
可落地的DDD(6)-工程结构
在分布式架构下,MVC比DDD,要乱的多!
其实,工程结构的存在作用目的,是为了承载工程系统开发的模型划分,定义工程服务开发过程中实施标准。说白了,就是你在工程实现时,在哪个层访问数据库、哪个层使用缓存、哪个层调用外部接口、哪个层做功能实现,这就是工程框架结构定义的目的。
小傅哥
2024/07/25
3550
在分布式架构下,MVC比DDD,要乱的多!
如何避免写出烂的业务代码(2)- DDD整改
何避免写出烂的业务代码(1)一文中介绍过如何避免写出烂的业务代码,这边谈一谈领域驱动模型的实践
方丈的寺院
2019/08/05
8210
如何避免写出烂的业务代码(2)- DDD整改
领域驱动设计(DDD):三层架构到DDD架构演化
在前文中,我从基础代码的角度探讨了如何运用领域驱动设计(DDD)来实现高内聚低耦合的代码。本篇文章将从项目架构的角度,继续探讨三层架构与DDD之间的演化过程,以及DDD如何优化架构的问题。
付威
2023/10/17
2.4K0
领域驱动设计(DDD):三层架构到DDD架构演化
从MVC到DDD,该如何下手重构?
大家好,我是技术UP主小傅哥。MVC讲解了,DDD讲解了。接下来这个章节,我们讲讲从MVC到DDD的重构!
小傅哥
2023/11/09
3.7K4
从MVC到DDD,该如何下手重构?
DDD-经典四层架构应用
根据DDD领域驱动设计原则,对应的软件架构也需要做出相应的调整。 我们常用的三层架构模型划分为表现层,业务逻辑层,数据访问层等,在DDD分层结构中既有联系又有区别, 个人认为主要有如下异同:
烂猪皮
2020/11/02
6.6K0
DDD-经典四层架构应用
可落地的DDD(5)-战术设计
本篇是DDD的战术篇,也就是关于领域事件、领域对象、聚合根、实体、值对象的讨论。也是DDD系列的完结篇。 这一部分在我们团队争论最多的,也有很多月经贴,比如对资源库的操作应该放在领域服务还是领域对象中。 聚合根应不应该暴露给外部,还是要转成DTO。这些问题我们讨论了大半年,最后大家基本达成了共识,在当前的业务规模下, 这些问题没那么重要,可东可西。不会对代码的质量有啥大的影响。关于DDD的实践,与团队的水平、业务复杂度息息相关。我们的经验并不一定就适用你们团队。我将战术篇的这么多的内容放在了一篇文章中,并且大部分都是引用之前的讨论、总结。 原因还是在于我内心深处并没有觉得战术篇的实践给我们团队带来多么大的改变。战略篇的是我认为更重要的。
方丈的寺院
2019/08/05
1K0
可落地的DDD(5)-战术设计
优秀的代码都是如何分层的?
说起应用分层,大部分人都会认为这个不是很简单嘛 就controller,service, mapper三层。看起来简单,很多人其实并没有把他们职责划分开,在很多代码中,controller做的逻辑比service还多,service往往当成透传了,这其实是很多人开发代码都没有注意到的地方,反正功能也能用,至于放哪无所谓呗。这样往往造成后面代码无法复用,层级关系混乱,对后续代码的维护非常麻烦。
程序员小明
2019/10/10
3.8K0
优秀的代码都是如何分层的?
ddd初探--落地实践
ddd出现的意义在于从业务的角度而不是技术的角度去解决软件的复杂性,正如某位大师所言:“program is logic and control”,所有的程序本质上就是两件事:逻辑和控制,而逻辑则是决定了复杂性的下限。举个例子,商品交易的业务逻辑复杂性天然就胜过im聊天的业务逻辑,这种时候无论怎样拆解,它的业务复杂性就摆在这里,而控制是我们尽可能用最优的手段去实现我们的逻辑,这里有点类似于面向对象中,接口和实现的感觉,但又不局限于此。
用户8717915
2021/07/01
6150
ddd初探--落地实践
一文探寻学习DDD的意义
《阿甘正传》中,阿甘开始了不停地跑步,一段时间后,后面就有了很多追随者一起跑,他们为什么跑哪?
从大数据到人工智能
2023/02/21
3130
一文探寻学习DDD的意义
从MVC到DDD的架构演进
DDD这几年越来越火,资料也很多,大部分的资料都偏向于理论介绍,有给出的代码与传统MVC的三层架构差异较大,再加上大量的新概念很容易让初学者望而却步。本文从MVC架构角度来讲解如何演进到DDD架构。
落寞的鱼丶
2022/02/21
1.4K0
《ArchSummit:从珍爱微服务框架看架构演进》
今年的ArchSummit的主题是“数字化转型下的架构升级”,主要聚焦:云原生、研效提升、IoT 系统架构、微服务架构、低代码系统、出海业务架构、人工智能与机器学习、企业数字化转型、前端 Serverless 研发体系、金融领域数字化转型、大数据实践与应用等领域。
后台技术汇
2022/11/08
5850
《ArchSummit:从珍爱微服务框架看架构演进》
相关推荐
DDD实战之二:看看代码结构长啥样
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验