项目模块化

在企业项目中,包层次结构和类关系可能变得非常复杂。 将代码分成模块是一项艰巨的任务,因为它要求您能够清楚地识别功能边界,例如,将业务逻辑与数据持久逻辑分开。

耦合性和内聚性

两个主要因素将决定实现项目关注点分离的容易程度:耦合和内聚。 耦合衡量特定代码工件(例如类)之间关系的强度。 内聚性是指模块的组件所属的程度。 代码的耦合性越低,内聚性越高,项目的重组就越容易。 教授良好的软件设计实践超出了本书的范围,但是您应该牢记两个指导原则:最小化耦合和最大化内聚。

Spring 框架是正确实现模块化架构的一个例子。 Spring 是一个开源框架,提供许多企业 Java 应用程序所需的广泛服务。 例如,简化的 MVC Web 应用程序开发或事务管理的服务支持功能作为 JAR 文件进行分发。 如果服务需要不同模块提供的功能,则服务相互依赖。 图 6.1 显示了 3.x 版本的所有 Spring 模块及其相互关系。

image 2024 04 03 17 12 17 723
Figure 1. 图6.1 Spring的模块化架构

Spring 的架构乍一看可能看起来很可怕。 它定义了许多相互依赖的组件。 但实际上,您不需要将包含所有组件的整个框架导入到您的项目中。 您可以选择要使用的框架服务。 值得庆幸的是,组件之间的依赖关系是通过元数据指定的。 使用 Gradle 的依赖管理使解决这些传递依赖变得轻而易举。

在以下部分中,您将模块化待办事项应用程序并使用 Gradle 的多项目功能来构建它。 由于目前代码库有限,这对于 Spring 框架的开发人员来说将是一项容易得多的任务。 我们将首先确定适合您的应用程序的模块。

识别模块

让我们回顾一下您已经为待办事项应用程序编写的代码,以找到其自然边界。 这些边界将帮助您将应用程序代码分解为模块。 以下目录树展示了现有的项目结构:

.
└── src
    └── main
        ├── java
        │     └── com
        │           └── manning
        │                 └── gia
        │                       └── todo
        │                             ├── model
        │                             │     └── ToDoItem.java
        │                             ├── repository
        │                             │     ├── InMemoryToDoRepository.java
        │                             │     └── ToDoRepository.java
        │                             └── web
        │                                   └── ToDoServlet.java
        └── webapp
                ├── WEB-INF
                │       └── web.xml
                ├── css
                │     ├── base.css
                │     └── bg.png
                └── jsp
                      ├── index.jsp
                      └── todo-list.jsp

通过将具有特定功能的类分组到包中,您已经很好地分离了应用程序的关注点。 您将使用这些包作为查找应用程序功能边界的指南:

  • 模型:待办事项的数据表示

  • 存储库:待办事项的存储和检索

  • Web:用于处理 HTTP 请求并在浏览器中呈现待办事项和功能的 Web 组件

即使在相当简单的应用程序中,这些模块之间也存在关系。 例如,存储库模块中的类使用模型数据类将数据传入和传出数据存储。 图 6.2 给出了所有建议模块及其关系的全貌。

image 2024 04 03 17 18 57 086
Figure 2. 图 6.2 待办事项应用程序的建议模块

考虑到已识别的模块及其关系,您可以开始将它们从单个项目中分离出来。

重构为模块

将现有项目结构重构为已识别的模块很容易。 对于每个模块,您将创建一个具有适当名称的子目录,并将相关文件移到其下面。 每个模块的默认源目录 src/main/java 将保持不变。 唯一需要默认 Web 应用程序源目录 src/main/webapp 的模块是 Web 模块。 以下目录树显示了模块化项目结构:

.
├── model
│     └── src
│           └── main
│                 └── java
│                       └── com
│                             └── manning
│                                     └── gia
│                                          └── todo
│                                               └── model
│                                                     └── ToDoItem.java
├── repository
│       └── src
│             └── main
│                   └── java
│                         └── com
│                              └── manning
│                                     └── gia
│                                           └── todo
│                                                 └── repository
│                                                       ├── InMemoryToDoRepository.java
│                                                       └── ToDoRepository.java
└── web
      └── src
          └── main
                ├── java
                │     └── com
                │          └── manning
                │                 └── gia
                │                       └── todo
                │                             └── web
                │                                   └── ToDoServlet.java
                └── webapp
                      ├── WEB-INF
                      │     └── web.xml
                      ├── css
                      │     ├── base.css
                      │     └── bg.png
                      └── jsp
                            ├── index.jsp
                            └── todo-list.jsp

就是这样——您模块化了待办事项应用程序。 现在是时候处理构建基础设施了。