Java中的激进模块化

时间:2014-05-01 18:09:15

标签: java

开发团队我是写作的一部分,并且仍然维护着纯Java意大利面条代码的代码库。其中大部分是在我加入这个团队之前实施的。

我的背景是Python / Django开发,Django社区真正强调“可插拔性” - Django“应用程序”(模块)的一个特性,它主要暗示“一件事和一件好事”,可重用性,松散耦合,一个干净,有意识的API。一旦我曾经工作过的Django团队开始“得到它”,我们几乎没有问题与凌乱,紧密耦合的大量单片代码。

我们的实践涉及在我们打算使用应用程序的Django项目之外开发Django应用程序(Django开发人员的常见做法,从我收集的内容)每个人甚至住在一个Git存储库中,与整体存储库不同Django项目。

现在,我们有机会重构我们的大部分意大利面条代码,在我看来,我从Django社区学到的一些内容应该在这里应用。简而言之,我希望看到我们的新代码库是作为一系列“可插拔”模块开发的,每个模块都假设它不能访问其他模块(除了理性依赖的模块之外)。我相信这应该能够很好地将正确的软件设计原则推向整个团队。

所以,我所倡导的是在我们的新(Spring)项目中每个“功能”都有一个单独的存储库。每个人都有自己独立的构建过程,结果将是.jar。我们还有一个项目级事物(JSP,静态文件等)的存储库,它的构建过程会生成.war。 .jars不会放在.war中,而是被视为Gradle依赖(与第三方依赖相同)。

现在我必须把它卖给老板。他被问到了这个计划的先例。显而易见的地方是开源项目,但如果项目分布在多个存储库中,则可能是多个项目。所以,也许我正在寻找某种套房。 Spring本身看起来很有前途,但我找不到其他很多。

我的问题是(并且对于长篇故事感到抱歉):

  • 有没有这样的先例?
  • 有哪些例子?
  • 有没有任何文件(即使只是一篇博文会有所帮助),还有这样的提倡吗?
  • 有关实施此建议的任何建议吗?
  • 这是个好主意吗?

提前致谢!

编辑:是否重构不是问题。我们已经决定对我们的大部分代码做出一些重大改变 - 实际上并非主要是为了“使其更清洁”。我的问题是我们的计划项目结构是否健全以及如何向决策者证明其合理性。

5 个答案:

答案 0 :(得分:3)

以下问题更重要的是将代码放在磁盘或工件中的位置:

如果你不明白,那你已经失败了。

您所描述的不是重构,而是使用更可口的名称重写:

除非您已经在单元测试中涵盖了100%的代码;当(不是)这种努力失败时,某人可能会被解雇,可能是多次!

即使进行了令人敬畏的单元测试,有人也会错过一些东西,有人会在最终在生产中被发现时堕落,通常是在数月无声地破坏数据之后。

语义很重要:

根据定义,删除Struts并替换为Spring 重构 重写。重构将从Struts 1.1转移到2.0,取代Struts意味着用其他东西替换所有Struts代码,根据定义重写而不是重构。

工作软件有很多伪装:

企业总是认为他们拥有工作

错过最后期限,介绍一个错误,无论多么轻微,失去一个功能,无论多么轻微,误解未记录的过程和改变的东西,无论多么轻微甚至更好。他们只是在寻找任何问题的弱点或潜在的麻烦来传播FUD,并确保你的努力是失败的,至少在大多数时间。

所有这些事情都会花费你和你的团队的政治资本,有人会为这些事情做好准备,无论多么无辜或无价值,都会感到失败!

预计结果:

最有可能是你和/或其他"非Java"开发人员而不是创建此工作系统的核心Java人员,即非Java"重构的人(在这种情况下重写的代码字)并按时交付破损和不完整或没有按时交付或根本没有交付。

答案 1 :(得分:1)

我认为可以在Java和Python中找到好的和坏的实现的例子。

春天确实是一个很好的起点。它强调良好的分层,设计界面等。我推荐它。

Spring的分层是“水平的”。如果“模块”对您来说意味着“业务功能”,则给定层中将存在多个模块。

Plugable建议采用更垂直的方法。

攻击它的另一种方法可能是将系统分解为一组独立的REST Web服务。完全从界面中分离功能。这样,服务可以由Web,移动或任何其他客户端共享。

这将需要严格隔离服务和数据源的所有权。单个Web服务将拥有/管理大量数据。

我建议查看Michael Feathers的书"Working Effectively With Legacy Code"。它已经十年了,但在亚马逊上仍然备受推崇。

我喜欢REST Web服务方法的一件事是您可以隔离功能并在时间和预算允许的情况下执行这些功能。创建并测试服务,让客户运用它,继续前进。如果事情没有太多耦合,你可以通过这种方式进入应用程序。

答案 2 :(得分:0)

重构整个应用程序并非易事,特别是如果代码是硬连线的,如上所述。如果 Pluggablity 是一个重要的目标,我会推荐Grails / Groovy。

如果您能以某种方式识别视图,控制器和业务逻辑,或者更好的服务。您可以重用一些现有代码。 grails / groovy的好处是你可以将JSP / JAVA与GSP / GROOVY结合起来。

同样,这真的很难卖,而且grails可能是一个缓解重构痛苦的好框架。

答案 3 :(得分:0)

我建议观看领域驱动设计的创始人Eric Evans的“处理遗留代码的四种策略”:http://dddcommunity.org/library/evans_2011_2/

它可能无法完全回答您的问题,但它提供了可能有助于您努力的论据和策略。

答案 4 :(得分:0)

每个组件都在自己的罐子里,但战争中不包含罐子?应该怎么做?甚至第三方文集都包含在战争中。除了容器提供的那些。关于jsp的东西:Can I serve JSPs from inside a JAR in lib, or is there a workaround?