由Spring应用的瑕疵谈谈DDD的概念与应用

举报
aoho 发表于 2021/06/02 14:40:28 2021/06/02
【摘要】 Spring 框架已经成为构建企业级 Java 应用事实上的标准了,众多的企业项目都构建在 Spring 项目及其子项目之上,特别是 Java Web 项目,很多都使用了 Spring 并且遵循着 Web、Service、Dao 这样的分层原则,下层向上层提供服务;不过Petri Kainulainen在其博客中却指出了众多 Spring Web 应用的最大瑕疵。多数有经验的程序开发者都应该...

Spring 框架已经成为构建企业级 Java 应用事实上的标准了,众多的企业项目都构建在 Spring 项目及其子项目之上,特别是 Java Web 项目,很多都使用了 Spring 并且遵循着 Web、Service、Dao 这样的分层原则,下层向上层提供服务;不过Petri Kainulainen在其博客中却指出了众多 Spring Web 应用的最大瑕疵。

多数有经验的程序开发者都应该听说过DDD,并且尝试过将其应用在自己的项目中。不知你是否遇到过这样的场景:你创建了一个资源库(Repository),但一段时间之后发现这个资源库和传统的DAO越来越像了,你开始反思自己的实现方式是正确的吗?或者,你创建了一个聚合,然后发现这个聚合是如此的庞大,它为什么引用了如此多的对象,难道又是我做错了吗?

本文将会谈谈有关领域驱动设计,和领域驱动设计中使用贫血、失血和充血模型。

Spring 应用的瑕疵

现在大部分应用Spring框架的Java Web应用都相当关注单一职责原则和关注分离原则,但是在此之上却诞生了一些不太好的反模式和设计原则,比如:

  • 领域模型对象只是用来存储应用的数据(领域模型使用了贫血模型这种反模式)。
  • 业务逻辑位于服务层中,管理域对象的数据。
  • 在服务层中,应用的每个实体对应一个服务类。

使用 Spring 框架构建应用的开发者很乐于谈论依赖注入的好处。但遗憾的是,他们很多人并没有在其应用中很好地利用其优势,如单一职责原则和关注分离原则。如果仔细看看基于 Spring 的 Web 应用,你会发现很多都是使用如下这些常见且错误的设计原则来实现的:

这类设计原则的应用非常广泛,我现在所在的Java Web项目就是使用这样的设计原则进行架构设计的,基本都是常见的三层或多层架构,他们大概是什么样的呢?

  • Web层(俗称展现层吧,Presentation Layer):接收用户输入,将数据传至服务层;
  • 服务层(Service Layer,可以叫Business Logic Layer):事务边界,处理业务逻辑、权限管理与授权,并与存储层通信;
  • 存储层(Data access layer):与数据库进行通信,对数据进行持久化。

image.png

但是发现什么没有?问题出在了服务层,他承受了太多的职责,像事务管理、业务逻辑、权限检查等等,这违反了单一职责原则和关注分离原则,并且产生了大量的依赖和循环依赖。当业务复杂度上升时,服务层所包含的代码将会非常庞大和复杂,直接导致了测试成本的上升。服务层主要有两个问题:

  • 应用的业务逻辑来自于服务层。

业务逻辑散落在服务层。如果需要查看某个业务规则是如何实现的,我们需要先找到它。此外,如果有多个服务类都需要相同的业务规则,那么会将这个业务规则从一个服务复制到另一个服务中,大量的代码重复。

  • 每个领域模型类在服务层中都有一个服务类。

这违背了单一职责原则:单一职责原则表明每个类都应该只有一个职责,这个职责应该完全被这个类所封装。它的所有服务都应该与这个职责保持一致。

如何改善现状,下面具体介绍领域驱动设计的相关概念和实施策略。

小结

本文通过Spring Web应用的瑕疵引出改善的措施,下面的文章将会介绍领域驱动开发的相关概念和设计策略。

订阅最新文章,欢迎关注我的公众号:aoho求索

参考

  1. Spring Web 应用的最大瑕疵
  2. 领域驱动设计(DDD)
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。