如何模块化(大型)Java App?

时间:2009-05-19 07:03:26

标签: java maven-2 refactoring modularity

我手边有一个相当大的(几个MLOC)应用程序,我想分成更易于维护的单独部分。目前,该产品由大约40个Eclipse项目组成,其中许多项目具有相互依赖性。仅这一点使得连续构建系统变得不可行,因为每次签入都需要非常重建。

是否存在如何

的“最佳实践”方式
  • 识别可立即分离的部分
  • 直观地记录相互依赖性
  • 解开现有代码
  • 处理我们需要应用于库的“补丁”(目前通过将它们放在实际库之前的类路径中来处理)

如果有(免费/开放)工具支持这一点,我会很感激指点。

即使我对Maven没有任何经验,但它似乎强制采用非常模块化的设计。我现在想知道这是否可以迭代地进行改装,或者一个项目是否必须从一开始就考虑模块化。

编辑2009-07-10

我们正在使用Apache Ant/Ivy拆分一些核心模块。非常有用且设计精良的工具,而不是像maven那样强加给你。

我写了一些更一般的细节和个人意见,说明我们为什么要在我的博客上这样做 - 在这里发帖太长,也许每个人都不感兴趣,所以请自行决定:www.danielschneller.com

7 个答案:

答案 0 :(得分:9)

使用OSGi可能非常适合您。它允许从应用程序中创建模块。您还可以以更好的方式组织依赖项。如果您正确定义了不同模块之间的接口,则可以使用持续集成,因为您只需要在签入时重建受影响的模块。

OSGi提供的机制将帮助您解开现有代码。由于类加载的工作方式,它还可以帮助您更轻松地处理补丁。

Some concepts of OSGi that seem to be a good match for you, as shown from wikipedia:

框架在概念上分为以下几个方面:

  • Bundles - Bundles是普通的jar组件,带有额外的清单头。
  • 服务 - 服务层通过为普通旧Java对象(PO​​JO)提供publish-find-bind模型,以动态方式连接bundle。
  • 服务注册表 - 管理服务的API(ServiceRegistration,ServiceTracker和ServiceReference)。
  • 生命周期 - 生命周期管理的API(安装,启动,停止,更新和卸载软件包)。
  • Modules - 定义依赖关系的封装和声明的层(bundle如何导入和导出代码)。
  • 安全性 - 通过将捆绑功能限制为预定义功能来处理安全性方面的层。

答案 1 :(得分:6)

第一:好运&好咖啡。你需要两个。

我曾经遇到过类似的问题。具有糟糕循环依赖性的遗留代码,甚至在来自不同包(如org.example.pkg1.A)的类之间取决于org.example.pk2.B 反之亦然。

我从maven2和新的eclipse项目开始。首先,我尝试确定最常见的功能(日志层,通用接口,公共服务)和创建的maven项目。每次我对某个部件感到满意时,我都会将该库部署到中央nexus存储库,以便几乎可以立即用于其他项目。

所以我慢慢地完成了各个层面的工作。 maven2处理了依赖项,m2eclipse插件提供了一个有用的依赖视图。 BTW - 将eclipse项目转换为maven项目通常并不困难。 m2eclipse可以为你做,你只需要创建一些新的文件夹(如src / main / java)并调整源文件夹的构建路径。只需一两分钟。但是如果您的项目是eclipse插件或rcp应用程序,并且您希望maven不仅可以管理工件,还可以构建和部署应用程序,那么期望更多的困难。

对于意见,eclipse,maven和nexus(或任何其他maven存储库管理器)是一个很好的基础。你很幸运,如果你有一个很好的系统架构文档这个架构真的实现了;)

答案 2 :(得分:3)

我在小代码库(40 kloc)中有类似的经历。没有“规则”:

  • 使用编译而没有“模块”以查看其使用情况
  • 我从“叶子模块”开始,没有其他依赖的模块
  • 我处理了循环依赖(这是一个非常容易出错的任务)
  • 与maven有很多可以部署的文档(报告) 在CI过程中
  • 使用maven,你可以随时看到在netbeans中使用网站中的内容(使用一个 非常好的有向图)
  • 使用maven,您可以在代码库中导入库代码,应用源补丁和 使用您的产品进行编译(有时这很容易,有时非常容易 难)

同时检查依赖性分析器:
(来源:javalobby.org

Netbeans的:


(来源:zimmer428.net

答案 3 :(得分:1)

Maven很难迁移到现有系统。然而,它可以毫不费力地应对100多个模块项目。

答案 4 :(得分:1)

您需要决定的第一件事是您将迁移到哪种基础设施。它应该是许多独立维护的模块(转换为单个Eclipse项目)还是将它视为一个版本化和部署的整个代码块。第一个非常适合迁移到Maven之类的构建环境 - 后者可以同时拥有所有源代码。

在任何情况下,您都需要运行持续集成系统。您的第一个任务是自动构建代码库,这样您就可以让CI系统监视源存储库并在更改时重建它。我决定在这里使用非Maven方法,并且我们专注于拥有一个简单的Eclipse环境,因此我使用ant4eclipse和Team ProjectSet文件(我们仍然使用它)创建了一个构建环境。

下一步将摆脱循环依赖 - 这将使您的构建更简单,摆脱Eclipse警告,并最终允许您进入“结帐,编译一次,运行”阶段。这可能需要一段时间:-(当你迁移方法和类时,不要移动它们,而是提取或委托它们并留下它们的旧名称并标记它们已被弃用。这将把你的解开与重构分开,并允许代码“在“您的项目之外仍然使用项目中的代码。

您将从源存储库中受益,该存储库允许移动文件和保留历史记录。 CVS在这方面非常薄弱。

答案 5 :(得分:0)

我不推荐使用Maven作为遗留源代码库。它可能会给你带来许多麻烦,只是试图让一切都适应它。

我认为你需要的是做一个项目的架构布局。工具可能会有所帮助,但最重要的部分是组织模块的逻辑视图。

答案 6 :(得分:0)

这不是免费的,但是Structure101会给你提供与你获得所有要点的工具支持一样好的东西。但是对于记录我有偏见,所以你可能也想看看SonarJ和Lattix。 ; - )