可落地的DDD的(2)-为何说MVC工程架构已通过时

摘要

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

mvc的问题

一般一个先后端分离的系统,后端工程系统结构图一般下面这样
在这里插入图片描述前端

1. 四层 controller/service/manager/mapper

  2. 不能够同级调用

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

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

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,或者其余方法论。

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

由于这些约束,都是强迫你去思考,去作职责的思考,去作模块的封装。若是你/你团队成员已经领会其中的道理并很好的运用,还须要这些条条框框干嘛呢?

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

相关阅读

http://www.javashuo.com/article/p-ogvnstav-md.html

关注【方丈的寺院】,第一时间收到文章的更新,与方丈一块儿开始技术修行之路
在这里插入图片描述

相关文章
相关标签/搜索