15

我被指派在一个巨大的 Java 项目上做一些工作,开发人员多次迭代的影响是显而易见的。没有标准的编码风格、格式、命名约定或类结构。这是一个美好的一天,当我遇到一个使用 Javadoc 的课程时,单元测试是一个快乐的白日梦。

到目前为止,我们这些参与该项目的人一直在“融入”,适应我们正在从事的任何课程的现有惯例,但现在是时候强加一些秩序和一致性了。

这是一项艰巨的挑战,我正在寻找人们可能对此类任务提出的任何建议。是否有任何特别有效的策略或需要注意的陷阱?尝试一下是个好主意吗?

编辑补充:我不想给人留下这个项目很糟糕的印象——它实际上设计得很扎实,而且基本上写得很好。它只是感觉它的年龄和维护的必然性......

4

9 回答 9

11

我发现 Eclipse 对于此类操作来说是一个非常强大的工具。

很多人都对命令行工具和基于模式的文本编辑器发誓进行编程,但使用完整的 IDE 进行重大重构有很大的优势:

  • 自动实时编译会在错误发生时以及发生的任何地方向您显示错误。仅仅因为您进行了更改并且课程中没有任何内容或立即打包中断并不意味着您没有在其他地方创建问题。红旗将在 eclipse 中的包树上直接引导您找到它们。
  • 基于图形的重命名和移动。重命名代码元素的影响可能比您所知道的要大得多。Eclipse 将向您显示相关元素的每个实例的详细信息以及重命名将如何更改它。
  • 自动导入管理使您可以省去处理确保所有导入井井有条的工作。Eclipse 会在使用时自动添加导入,并用动作灯泡标记未使用的导入,以便一键删除。
  • 使用代码样式来确保所有源文件对所有内容都使用相同的格式。空格、缩进、换行、括号都可以为您设置格式。这适用于您创建新代码以及更新现有文件。

除了 Eclipse 的工具集之外,您还可以考虑利用其他现代 Java 工具来确保您的代码始终正常运行。

  • 测试套件允许您不断确保您所做的任何更改不会对项目的功能产生负面影响。如果你要重构一个特性,写两三个测试用例来演示它的工作方式。确保它们在任何更改之前和之后运行。这是在问题成为问题之前发现问题的最简单方法。
  • 使用 Maven 等工具来协助处理依赖关系、测试、编译和部署。不要再浪费时间做任何上述任务。专注于编写完成工作的代码。

编辑:

我个人也更喜欢 Eclipse,因为我是进行重构的人,而不是对我的代码几乎一无所知的自动化工具。

于 2010-10-19T18:07:53.837 回答
6

您可以使用工具对项目中的源代码强加一种通用格式。除此之外,请参阅 Michael Feathers 的Working Effectively with Legacy Code(其中“遗留代码”被定义为“没有单元测试的代码”),它描述了如何逐渐将遗留代码转变为经过充分测试和可测试的代码。

于 2010-10-19T18:07:05.867 回答
3

从整体类开始并将它们分解(超过 500 条语句,不包括注释和仅带有大括号的行)。引入接口,然后是依赖注入。

于 2010-10-19T18:30:32.190 回答
3

在这种情况下我喜欢做的是:

  1. 首先将项目转换为使用 Maven 构建,以便我知道依赖项是什么版本。
  2. 这也为我提供了一些不错的代码质量报告,可用作基准,包括 checkstyle、findbugs、pmd 和代码覆盖率。
  3. 而且我(和许多其他人)已经习惯了这种结构,所以我们知道在哪里可以找到源代码、单元测试、资源等。
  4. 如果它是一个大型项目,那么 maven 多模块项目布局可能是正确的结构。
  5. 如果它目前是一个大泥球,那么它将成为核心模块,以后可以重构为单独的模块。
  6. 标准的maven 目录结构为单元测试提供了空间,因此鼓励了单元测试。
  7. 单元测试是开始重构之前的关键先决条件。
  8. 使用Hudson建立持续集成构建周期。
于 2010-10-19T18:18:58.540 回答
2

我已经经历了几次这个过程,我发现解决方案需要了解以下内容:

  • 解决这些问题的概念会引起政治动荡吗?
  • 现在有一个公认的标准来说明这些东西的外观/格式吗?
  • 有很好的测试用例吗?

政治局势是最难缓解的,基本上没有人喜欢横向移动的想法,并且执行代码格式和命名约定的过程在很大程度上是横向移动。如果你能拿出一套可靠的指标来证明你的决定是正确的,那么你的横向运动就可以被伪装成向前运动。我发现这里最好的指标是

“一套一致的编码标准将导致: - 减少 30% 的错误 - 30% 的开发速度 - 降低 80% 的维护成本 - 100% 的我们编码人员将更加高兴这一变化”

不仅仅是把这些数字从空中拉出来是诀窍。能够证明这一点。

显然,除非您从当前添加到项目中的人员那里购买,否则开始这项工作是没有意义的。每个人都必须同意并开始将这些理想重新安装到当前存在的代码中。请记住,不是每个人都使用 IDE(例如,我在 VIM 中编写所有 java 代码),因此您应该确保这种格式在 wiki 上规定所有人都可以看到(尤其是新团队成员),并且 wiki 页面有各种编辑器的下载正在使用。

由于我们很可能不仅在讨论代码格式,而且还讨论变量重命名和模式更改,这些都会影响您的类的公共 api,因此您确实需要确保您拥有一组非常稳定的测试用例。如果缺少测试用例,那么您应该始终从外部开始 - 为您的测试建模,以便它们像您的用户一样进行交互。然后你就可以带着一定的信心去经历和重构。一旦你的代码与你的梦想相似,你就可以进入并在每个对象附近添加测试。没有什么比创建所有测试用例、然后更改 API 并不得不更改所有测试用例更痛苦的了;每次我看到这种情况发生时,都会导致测试覆盖率大幅下降。

于 2010-10-19T19:32:25.587 回答
1

我的建议是在你的构建系统中添加类似 Checkstyle 的东西。很难让管理层接受一次性进行全面检修的想法。设计一套你认为好的风格指南,并在 Checkstyle 中实现它们并将其添加到你的构建中。

然后,要求所有新的代码签入都不会破坏 Checkstyle。这意味着无论何时你在课堂上工作,你都会把它提高到标准。如果只是在投入一段时间之前你必须做的一些事情,那么你似乎根本不会做任何额外的工作。

此外,还有用于 Eclipse 的 checkstyle 插件。

于 2010-10-19T18:09:28.280 回答
0

我还建议使用 IDE 的功能来提高代码质量。对于 Eclipse 这我会做什么:

在首选项 java > code style > formatter - 定义您自己的格式并添加它。之后右键单击项目和源<清理。选择 sustom 配置文件并配置。你可以在这里做很多事情,比如代码格式化、清理导入、将遗留的 for 循环转换为增强的循环、清理未使用的代码等等。

之后我会做其他人建议的事情,比如使用 checkstyle、pmd、findbugs 等等。

于 2010-10-19T19:07:04.037 回答
0

这是一项相当普遍的任务,不是很快乐,但也不是噩梦……如果用其他语言(Perl、PHP、C++、-gasp-VB……)编码,情况可能会更糟;实际上,Java 是最适合您的方案的一种。

获得一个像样的 IDE (Eclipse) 并花时间了解依赖关系和调用周期。熟悉所有内容需要很长时间,因此请先尝试仅进行小的更改。

当缺乏文档时,IDE(和静态编译)有助于了解谁在使用哪个类或方法,并且您可以非常自信地进行重构。但首先尝试确定在哪些层/包/类中使用了反射(由您的代码显式,或由您的框架隐式 - 例如一些 getter 和 setter)。

有很多书专门讨论“再造遗留软件”和相关问题。

于 2010-10-19T18:17:21.083 回答
0

我有过这样的经历。我同意推荐 maven build、eclipse、Checkstyle、重构大类等的人的观点。我知道在开始工作之前您无法实现完整的测试覆盖率。我建议 1. 使用 checkstyle 或类似工具以批处理模式重新格式化代码 2. 在 Eclipse 中启用所有合理的警告,并重构导致此类警告的代码,如果这种重构是微不足道的。在其他情况下,将 @SupressWarning 和特殊的 TODO 放在稍后返回此代码。3. 使用缺陷驱动的自动测试,即为您将要更改的模块开发测试。

祝你好运!

于 2010-10-19T18:52:33.853 回答