随着项目的不断发展,需求的不断细化与添加,代码越来越多,结构也越来越复杂,这时候就会遇到各种问题

  • 不同方面的代码之间相互耦合,这时候一系统出现问题很难定位到问题的出现原因,即使定位到问题也很难修正问题,可能在修正问题的时候引入更多的问题。
  • 多方面的代码集中在一个整体结构中,新入的开发者很难对整体项目有直观的感受,增加了新手介入开发的成本,需要有一个熟悉整个项目的开发者维护整个项目的结构(通常在项目较大且开发时间较长时这是很难做到的)。
  • 开发者对自己或者他人负责的代码边界很模糊,这是复杂项目中最容易遇到的,导致的结果就是开发者很容易修改了他人负责的代码且代码负责人还不知道,责任追踪很麻烦。

将一个复杂项目拆分成多个模块是解决上述问题的一个重要方法。 拆分的好处

  • 多模块的划分可以降低代码之间的耦合性(从类级别的耦合提升到jar包级别的耦合)
  • 每个模块都可以是自解释的(通过模块名或者模块文档)
  • 模块还规范了代码边界的划分,开发者很容易通过模块确定自己所负责的内容

自解释性就是要求程序代码、配置、脚本能够充分清晰的表明自己的业务意图、业务步骤、参数类型、参数值范围、约束、修改方法等信息。

对于程序代码,类和对象名字要反映出执行者(actor)在场景中角色,通常采用名词命名。方法名字要充分反映业务意图。通常可以采用动词或动词短语命名。如果参数过多,使用具有结构的对象封装参数,而不是将参数胡乱塞入Map<String,Object>传递。同时,方法要充分注释,写清楚参数和返回值的含义,可能抛出的异常和其他需要注意的地方。脚本也是一种程序源代码,因此可采用和程序代码同样的原则。

模块拆分策略

推荐按照功能拆分,后期方便转换成微服务架构

按职责划分

  • –module-test

    • –module-test-service
    • –module-test-po
    • –module-test-controller
    • –module-test-dao
    • –module-test-common
    • –module-test-util

按功能拆分

例如,在电商系统中如下module

  • –module-test

    • –module-test-common公共部分
    • –module-test-order订单
    • –module-test-checkout购物车
    • –module-test-pay支付
    • –module-test-catory类目
    • –module-test-product商品
    • –module-test-price价格
    • –module-test-account账号

搭建多模块项目

搭建多模块项目,需要使用 maven 的继承和聚合,其中聚合负责将多个模块集中在一起进行管理,继承则负责各子模块中的公共配置

创建项目

我使用的是idea




删掉src

pom文件内容

创建子模块

在项目下创建子模块

套路与创建普通项目一致

注意变化


module 的 pom 文件发生了变化

新增了两段配置

<packaging>pom</packaging><modules><module>module-util</module>
</modules>

pom 是最简单的打包类型。不像jar和war,它生成的构件只有它本身。将 packaging 申明为 pom 则意味着没有代码需要测试或者编译,也没有资源需要处理。

由于我们使用了聚合,所以打包方式必须为pom,否则无法构建。

<modules><module>module-util</module>
</modules>

module的值是子模块相对于当前 POM 的路径。

再看子模块中的 pom


也是分成两个部分

<parent><groupId>com.wqlm</groupId><artifactId>module</artifactId><version>1.0-SNAPSHOT</version>
</parent><artifactId>module-util</artifactId>
<parent><groupId>com.wqlm</groupId><artifactId>module</artifactId><version>1.0-SNAPSHOT</version><!--<relativePath/>-->
</parent>

声明了该模块继承自 com.wqlm:module:1.0-SNAPSHOT,其实这里面还省略了
<relativePath></relativePath> 由于 relativePath 默认是 ../pom.xml 而我们的子项目确实在父项目的下一级目录中,所以是可以不用填写的

Maven首先在当前构建项目的环境中查找父pom,然后项目所在的文件系统查找,然后是本地存储库,最后是远程repo。

artifactId 是子模块的组件id,由于继承了父pom,所以groupIdversion 也可以不写,不写的话就默认继承自父pom

使用多模块

如上所示,在创建多个模块之后,可以在父pom中添加公共配置,然后所有的子模块都会继承这些配置。除此之外,还可以统一对子模块进行 编译打包安装… 操作

子模块间的依赖

如果子模块间相互依赖,需要在 dependency 中引入要依赖的子模块,如图

上图中子模块 module-common:1.0-SNAPSHOT 依赖了 module-util:1.0-SNAPSHOT

子模块间的相互依赖,需要管理好依赖项的版本号,否则容易依赖版本冲突。

简单来说就是把公共依赖及版本号在父 pom 中申明,子项目引入依赖时只需要指定 groupId、artifactId 不需要指定版本号

如下,先在父 pom 中申明依赖及版本号

再在子项目中引入依赖项,注意,不需要指定版本号,默认查找父pom中定义的版本号


在软件开发中,把一个大项目分拆为多个模块是降低软件复杂度的有效方法:


对于Maven工程来说,原来是一个大项目:


现在可以分拆成3个模块:


Maven可以有效地管理多个模块,我们只需要把每个模块当作一个独立的Maven项目,它们有各自独立的pom.xml。例如,模块A的pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.itranswarp.learnjava</groupId><artifactId>module-a</artifactId><version>1.0</version><packaging>jar</packaging><name>module-a</name><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><maven.compiler.source>11</maven.compiler.source><maven.compiler.target>11</maven.compiler.target><java.version>11</java.version></properties><dependencies><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version>1.7.28</version></dependency><dependency><groupId>ch.qos.logback</groupId><artifactId>logback-classic</artifactId><version>1.2.3</version><scope>runtime</scope></dependency><dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter-engine</artifactId><version>5.5.2</version><scope>test</scope></dependency></dependencies>
</project>

模块B的pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.itranswarp.learnjava</groupId><artifactId>module-b</artifactId><version>1.0</version><packaging>jar</packaging><name>module-b</name><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><maven.compiler.source>11</maven.compiler.source><maven.compiler.target>11</maven.compiler.target><java.version>11</java.version></properties><dependencies><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version>1.7.28</version></dependency><dependency><groupId>ch.qos.logback</groupId><artifactId>logback-classic</artifactId><version>1.2.3</version><scope>runtime</scope></dependency><dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter-engine</artifactId><version>5.5.2</version><scope>test</scope></dependency></dependencies>
</project>

可以看出来,模块A和模块B的pom.xml高度相似,因此,我们可以提取出共同部分作为parent:

<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.itranswarp.learnjava</groupId><artifactId>parent</artifactId><version>1.0</version><packaging>pom</packaging><name>parent</name><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><maven.compiler.source>11</maven.compiler.source><maven.compiler.target>11</maven.compiler.target><java.version>11</java.version></properties><dependencies><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version>1.7.28</version></dependency><dependency><groupId>ch.qos.logback</groupId><artifactId>logback-classic</artifactId><version>1.2.3</version><scope>runtime</scope></dependency><dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter-engine</artifactId><version>5.5.2</version><scope>test</scope></dependency></dependencies>
</project>

注意到parent的<packaging>pom而不是jar,因为parent本身不含任何Java代码。编写parentpom.xml只是为了在各个模块中减少重复的配置。现在我们的整个工程结构如下:

这样模块A就可以简化为:

<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>com.itranswarp.learnjava</groupId><artifactId>parent</artifactId><version>1.0</version><relativePath>../parent/pom.xml</relativePath></parent><artifactId>module-a</artifactId><packaging>jar</packaging><name>module-a</name>
</project>

模块B、模块C都可以直接从parent继承,大幅简化了pom.xml的编写。

如果模块A依赖模块B,则模块A需要模块B的jar包才能正常编译,我们需要在模块A中引入模块B:

    ...<dependencies><dependency><groupId>com.itranswarp.learnjava</groupId><artifactId>module-b</artifactId><version>1.0</version></dependency></dependencies>

最后,在编译的时候,需要在根目录创建一个pom.xml统一编译:

<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.itranswarp.learnjava</groupId><artifactId>build</artifactId><version>1.0</version><packaging>pom</packaging><name>build</name><modules><module>parent</module><module>module-a</module><module>module-b</module><module>module-c</module></modules>
</project>

这样,在根目录执行mvn clean package时,Maven根据根目录的pom.xml找到包括parent在内的共4个<module>,一次性全部编译。

小结

Maven支持模块化管理,可以把一个大项目拆成几个模块:

  • 可以通过继承在parent的pom.xml统一定义重复配置;
  • 可以通过<modules>编译多个模块。

Maven 模块管理相关推荐

  1. eclipse中用maven多模块管理,然后主项目无法调用其他被依赖项目里的方法,解决办法

    eclipse中用maven多模块管理,然后主项目无法调用其他被依赖项目里的方法,解决办法 参考文章: (1)eclipse中用maven多模块管理,然后主项目无法调用其他被依赖项目里的方法,解决办法 ...

  2. IDEA新建一个多maven模块工程(有图)

    对于一些大型的项目来说,将项目的各个模块理清并进行管理,便于后续项目的维护,使用maven管理是很方便的,它可以很好的构建模块来设计项目的整体结构,对一些小型的项目不建议使用 1.新建父maven模块 ...

  3. java idea 模块_使用IntelliJ IDEA搭建多maven模块JAVA项目

    一.新建项目和模块 步骤: 1. 新建一个项目,因为maven管理jar包非常方便,故此处建立一个maven项目:New Project->Maven->(Create from arch ...

  4. 使用IntelliJ IDEA搭建多maven模块JAVA项目

    一.新建项目和模块 步骤: 1. 新建一个项目,因为maven管理jar包非常方便,故此处建立一个maven项目:New Project->Maven->(Create from arch ...

  5. maven依赖管理_依赖管理和Maven

    maven依赖管理 Maven伟大而成熟. 几乎所有事物都总有解决方案. 您可能在组织项目上遇到的主要情况是依赖管理. 而不是每个项目都具有自己的依赖关系,您需要一种集中的方式来继承那些依赖关系. 在 ...

  6. Maven手工管理项目

    Maven手工管理项目 1.Maven手工管理简单项目 创建需要管理的项目目录 SwitchdeMacBook-Pro:webapps switch$ mkdir maven-restaurant S ...

  7. maven依赖管理(依赖配置、依赖传递、依赖冲突、依赖范围)

    文章目录 基本说明 依赖配置 依赖传递 直接依赖 间接依赖 依赖冲突 路径优先 声明优先 特殊依赖 可选依赖 排除依赖 可选依赖和排除依赖区别 依赖范围 总结 基本说明 这篇文章会介绍在maven中的 ...

  8. RDIFramework.NET ━ .NET快速信息化系统开发框架 V3.2-新增模块管理界面导出功能(可按条件导出)...

    RDIFramework.NET ━ .NET快速信息化系统开发框架 V3.2->新增模块管理界面导出功能(可按条件导出) 导出功能在很多应用场景中都需要,RDIFramework.NET V3 ...

  9. [笔记]解决m2eclipse给项目添加maven依赖管理时可能不给项目的build path...

    为什么80%的码农都做不了架构师?>>>    解决办法:在m2eclipse提供的菜单里关闭项目的Maven依赖管理,然后再启动Maven的依赖管理!!! 检查:1)查看项目的.c ...

最新文章

  1. Linux命令(基础)
  2. 网线制作(一根网线劈开给2台同时上网使用)
  3. win10上编译libharu库
  4. 从职场新人到企业高管,她是怎么做到的?
  5. c++ ftp服务端_重磅干货||五万字长文总结:C/C++ 知识(下篇)
  6. android pickerview 多行,Android-PickerView系列之介绍与使用篇(一)
  7. Clion 配置 opencv不显示图片Process finished with exit code -1073741515 (0xC0000135)
  8. vue脚手架 使用npm run dev 遇到的错误问题
  9. 儿童php钢板使用流程,8字钢板半骺板阻滞术治疗儿童下肢成角畸形
  10. Web前端基础体验学习过程1 HTML篇
  11. 基于ssm Vue+elementui农家乐管理系统java 项目源码介绍
  12. java-assured_接口自动化测试(rest-assured)
  13. BiliBili下载.flv视频文件重命名
  14. (实测可用)STM32CubeMX教程-STM32L431RCT6开发板(定时器Timer2)
  15. 微信小程序开发—消息推送
  16. 织梦DedeCMS管理员动态密码登录插件下载
  17. c语言建立可视化窗口,如何用C语言编程出可视化界面?
  18. 智能镜子制作_更智能的镜子及其制作方法
  19. web课程设计网页规划与设计:文化网站设计——中国水墨风书画艺术网站(12个页面)
  20. PHP中的排序函数sort、asort、rsort、krsort、ksort区别分析

热门文章

  1. Java Web学习总结(8)——使用Cookie进行会话管理
  2. 检查eth是否到账_税务检查视角:高新技术企业核查要点
  3. php返回ajax必须是数组,ajax返回数组,页面接收不到数据
  4. [VUE系列二]vue官方文档总结和整理
  5. 数据库优化查询的方法以及大访问量到数据库时的优化
  6. Oracle18C RPM安装介绍
  7. struct对象可能分配在托管堆上吗
  8. Apache Pulsar的多租户消息系统
  9. Swift - RunTime(动态性) 问题 浅析
  10. sencha touch 在安卓中横屏、竖屏切换 应用崩溃问题