Spring Web应用的最大瑕疵

Spring Web应用的最大瑕疵

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

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

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

可问题是:如果这种做法很普遍,那为什么说是不对的呢?下面来阐述一下。

旧习难改

Spring Web应用之所以看起来是这个样子原因在于这是人们长久以来的做法,旧习难改,特别是在高级开发者或是软件架构师强制开发人员这样做的时候。问题在于这些人非常擅于捍卫自己的观点。他们喜欢的一个论调就是应用应该遵循关注分离原则,因为它被划分成了几个层次,每个层次都有自己具体的职责。

一个典型的Spring Web应用会有如下几个层次:

  • Web层:负责处理用户的输入并向用户返回正确的响应。Web层只会与服务层通信。
  • 服务层:作为事务边界。它还负责授权并包含了应用的业务逻辑。服务层管理着领域对象模型并且与其他服务及存储层通信。
  • 存储/数据访问层:负责与所用的数据存储进行通信。

关注分离原则的定义是这样的:关注分离(Soc)是一种将计算机程序划分到不同部分的一种设计原则,这样每一部分都会有单独的关注点。虽然一个典型的Spring Web应用也在一定程度上遵循了这个原则,不过实际情况却是应用拥有一个整体的服务层,它包含了太多的职责了。更具体一些,服务层主要有两个问题:

首先,应用的业务逻辑来自于服务层。

这是个问题,因为业务逻辑散落在服务层。如果需要查看某个业务规则是如何实现的,我们需要先找到它才行,这可不是那么轻松的事情。此外,如果有多个服务类都需要相同的业务规则,那么开发人员很可能会将这个业务规则从一个服务复制到另一个服务中,这会导致维护的梦魇。

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

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

服务类存在大量的依赖和大量的循环依赖。一个典型的Spring Web应用的服务层没有包含只拥有一个职责的松耦合的服务,它更像是一个紧耦合的大量服务的集合。这使得它很难理解、维护与重用。看起来有点苛刻,不过服务层经常是Spring Web应用最容易出现问题的一环。幸好对我们来说还存在着希望。

推翻

目前的状况并不好,不过也不是完全没有希望的。下面我们来看看如何打破旧有的习惯。

首先,我们需要将应用的业务逻辑从服务层移动到领域模型类中。

为何要这么做呢,看看下面这个例子:

假设我是个服务类,你是个领域模型对象。如果我告诉你从房顶跳下来,那么你是否会拒绝呢?

将服务层的业务逻辑移动到领域模型类中有如下3个好处:

  • 根据合理的方式划分代码的职责。服务层会负责应用的逻辑,而领域模型类则负责业务逻辑。
  • 应用的业务逻辑只会位于一处。如果需要验证特定的业务规则是如何实现的,我们总是知道该去哪里寻找。
  • 服务层的源代码将会变得更加整洁,再不会包含任何复制粘贴的代码了。

其次,我们需要将特定于实体的服务划分为更小的服务,每个服务只有一个目标。

比如说,如果应用有一个服务类,它为与用户帐户相关的人与操作提供了CRUD操作,那么我们就应该将其划分到两个单独的服务类中:

  • 第1个服务提供人的CRUD操作。
  • 第2个服务提供与用户帐户相关的操作。

这么做有如下3个好处:

  • 每个服务类都有一套合理的职责。
  • 每个服务类的依赖会更少,这意味着他们不再是紧耦合的庞然大物了。他们是更加小巧且松耦合的组件。
  • 服务类更易于理解、维护与重用。

这两个简单的步骤可以帮助我们清理应用的架构,提升开发者的生产力和幸福度。现在,我们想知道如果所有这些都是必要的,那么该何时解决这些问题呢?

有时生命是黑白的

我经常听到有人说我们不应该过多的关注于“架构”,因为我们的应用很小并且很简单。虽然这个论调有一定的正确性,不过我们必须要记住一开始很小的项目最后会变得很大。如果不考虑这种情况,那么一旦发生状况,我们就会陷入到巨大的麻烦当中。在未知的水域中航行可不是个好做法,但我们必须要知道,泰坦尼克号在撞到冰山沉没时是在熟悉的航线中航行的。这种事情也会发生在我们的应用中。当事情变得无法控制时,我们必须要有勇气说不。

如果你打算改变,那么我推荐你阅读一下Olivier Gierke所写的“Whoops! Where did my architecture”(或是观看他在SpringOne2GX上关于这个项目的演讲)。但请注意,习惯的力量还是很强大的。

时间: 2024-09-28 04:59:15

Spring Web应用的最大瑕疵的相关文章

在Spring Web MVC环境下使用Dojo

开始之前 关于本教程 本教程主要探讨如何在 Spring Web MVC 环境中使用 Dojo 的 widget,示例应用使用了 dojox.data.DataGrid,一个 Dojo Toolkit 1.2 新增的 widget . Dojo widget 与服务器交换数据的格式有很多种,本教程主要探讨在 Ajax 编程中比较常用的 JSON 格式的数据.本教程示例演示了 dojox.data.DataGrid 组件与 Spring Web MVC 控制器之间交换数据的细节,其中,服务器端使用

Spring Web Flow 2中流管理的持久化:事务性Web流的持久化策略

Spring Web Flow 是一种新颖的 Java Web 框架,它扩展了 Spring MVC 技术.使用 Spring Web Flow 的应用开发围绕着定义为 Web 流的用例展开. 将开发工作区根据 Web 流进行组织使开发体验更有意义.更具上下文.此外,Spring Web Flow 对 JPA/Hibernate 持久化的支持也是其最重要的服务器端改进之一. 尽管 SpringSource 和 Spring Web Flow 项目组详细介绍了 Spring Web Flow,但是

用Spring Web Flow和Terracotta搭建Web应用

Spring Web Flow 引入了几种有状态数据域:request.flash.flow和conversation等,这让你能用新的方式来开发有状态Web应用.它也提供了定制应用状态管理的扩展点. Terracotta for Spring是通过在多个JVM集群来给基于Spring的应用提供高可用性的运行时.它给Spring Web Flows的所有域都提供了透明的声明式集群服务(普通的Spring beans同样适用). 在这篇文章中我们会首先给你一个Spring Web Flow和Ter

Spring Web Flow 2.0入门

实现示例应用的购物车流程,可按以下步骤操作: 在 /WEB-INF/lib 目录下导入相关类库 在 webmvc-config.xml 中添加与 Spring Web Flow 集成的配置 添加 Spring Web Flow 的配置文件 webflow-config.xml 添加 flow 定义文件 shopping.xml 添加三个 jsp 页面 修改 index.jsp 在 /WEB-INF/lib 目录下导入相关类库 将以下几个 jar 包导入 /WEB-INF/lib 目录: org.

《精通Spring MVC 4》——第1章 快速搭建Spring Web应用 1.1Spring Tool Suite简介

第1章 快速搭建Spring Web应用 在本章中,我们将会直接接触代码并搭建一个Web应用,本书的其他章节将会基于该应用进行讲解. 在这里,我们将会使用Spring Boot的自动配置功能来构建应用,这样的话,就能完全避免使用样板式的配置文件. 本书中将会使用Gradle和Java 8,但是也不必为此感到担心.如果你还在使用Maven和更早版本的Java的话,相信你会发现这些技术也是很易于使用的. 很多官方的Spring教程同时提供了Gradle构建和Maven构建,因此,如果你决定继续使用M

Spring Web工程web.xml零配置即使用Java Config + Annotation

摘要: 在Spring 3.0之前,我们工程中常用Bean都是通过XML形式的文件注解的,少了还可以,但是数量多,关系复杂到后期就很难维护了,所以在3.x之后Spring官方推荐使用Java Config方式去替换以前冗余的XML格式文件的配置方式: 在开始之前,我们需要注意一下,要基于Java Config实现无web.xml的配置,我们的工程的Servlet必须是3.0及其以上的版本: 1.我们要实现无web.xml的配置,只需要关注实现WebApplicationInitializer这个

Spring Boot——2分钟构建spring web mvc REST风格HelloWorld

Spring Boot--2分钟构建spring web mvc REST风格HelloWorld 之前有一篇<5分钟构建spring web mvc REST风格HelloWorld>介绍了普通方式开发spring web mvc web service.接下来看看使用spring boot如何快速构建一个.   Spring Boot使我们更容易去创建基于Spring的独立和产品级的可以"即时运行"的应用和服务.支持约定大于配置,目的是尽可能快地构建和运行Spring应

Features of Spring Web MVC

21.1.1 Features of Spring Web MVC Spring Web Flow Spring Web Flow (SWF) aims to be the best solution for the management of web application page flow. SWF integrates with existing frameworks like Spring MVC and JSF, in both Servlet and Portlet environ

spring tool suit-sinple spring web maven加不到tomcat中。

问题描述 sinple spring web maven加不到tomcat中. spring tool suit新建的sinple spring web maven加不到tomcat中. 0.Preferences---server---Runtime Environments--add一个本地的tomcat 1.File---new---Spring Project--Simple Projects--Simple Spring Web Maven 然后右键 2.然后打开Servers 视图