4

我有一个项目(与图形算法有关)。是别人写的。

代码很可怕:

  • 公共领域,没有 getter/setter
  • 巨大的方法,全部公开
  • 一些类有超过 20 个字段
  • 一些类有超过 5 个构造函数(它们也很大)
  • 其中一些构造函数只留下许多字段null
    (所以我不能使某些字段成为最终字段,因为每隔一个构造函数都会发出错误信号)
  • 方法和类在两个方向上相互依赖

我必须把它改写成一个干净易懂的 API。

问题是:我自己不理解这段代码中的任何内容。

请给我一些关于分析和理解此类代码的提示。

我在想,也许有一些工具可以执行静态代码分析并给我调用图之类的东西。

4

10 回答 10

8

哦,亲爱的 :-) 我羡慕你,而不是同时……好吧,让我们一次做一件事。在设置代码分析工具之前,您可以自己解决其中的一些问题。通过这种方式,您将获得更好的理解,并且能够比使用简单的工具更进一步

  • 公共领域,没有 getter/setter
    • 让一切变得私密。您的规则应该是尽可能限制访问
  • 巨大的方法,全部公开
    • 在有意义的地方拆分并设为私有
  • 一些类有超过 20 个字段
    • 呃……Effective Java 2nd Ed 中的 Builder 模式是这方面的主要候选者。
  • 一些类有超过 5 个构造函数(它们也很大)
    • 听起来像伸缩构造函数,与上述相同的模式将有所帮助
  • 其中一些构造函数只是将许多字段留空
    • 是的,它是伸缩构造函数:)
  • 方法和类在两个方向上相互依赖
    • 这将是最不有趣的。尝试删除继承,除非您完全清楚它是必需的,并在适用的情况下通过接口使用组合

祝你好运,我们在这里为您提供帮助

于 2010-03-21T21:15:14.013 回答
6

哇!

我建议:编写单元测试,然后开始重构

* public fields, no getters/setters

首先将它们设为私有并“感受”对编译器错误的阻力作为衡量标准。

* huge methods, all public

理解它们的语义,尝试引入接口

* some classes have over 20 fields

在复杂的应用中很常见,不用担心

* some classes have over 5 constructors (which are also huge)

用建造者/创造者模式替换它们

* some of those constructors just left many fields null

看上面的答案

* methods and classes rely on each other in both directions

决定是否重写所有内容(老实说,我遇到了只需要 10% 的代码的情况)

于 2010-03-21T21:04:04.363 回答
3

好吧,eclipse 中的清理向导会刮掉相当大比例的污泥。

然后,如果您活得足够长,您可以将 Sonar 指向它并修复它抱怨的所有问题。

于 2010-03-21T21:00:11.620 回答
2

对于静态分析和调用图(没有图形,但有图形结构),您可以使用Dependency Finder

于 2010-03-21T21:06:08.857 回答
2

使用了解重构的 IDE,例如 IntelliJ。您不会遇到移动一个方法而其他五个类抱怨的情况,因为 IntelliJ 足够聪明,可以进行所有必需的更改。

单元测试是必须的。没有单元测试的重构就像没有安全网的高铁表演者。在开始漫长而艰难的攀登之前先买一个。

于 2010-03-21T21:15:49.207 回答
1

答案可能是:耐心和咖啡。

于 2010-03-21T21:08:13.933 回答
1

这是我会这样做的方式:

  1. 开始使用代码,例如从一个main方法中,就好像它被其他类使用一样——相同的参数,相同的调用顺序。在调试器中执行此操作,就像您看到此类所做的每个步骤一样。
  2. 开始为该功能编写单元测试。一旦你达到了合理的覆盖范围,你就会开始注意到这个类可能有太多的职责。

while ( responsibilities != 1 ) {

  1. 提取表示该类的一项职责的接口。
  2. 让所有调用者使用该接口而不是具体类型;
  3. 将实现提取到一个单独的类;
  4. 使用新接口将新类传递给所有调用者。

}

于 2010-03-21T21:14:07.247 回答
1

不是说一些人已经提到的声纳、FindBugs 等工具没有帮助,但没有魔术。从你确实了解的东西开始,为它创建一个单元测试,一旦它运行绿色,就开始逐个重构。记住要模拟依赖项。

于 2010-03-21T21:14:44.623 回答
0

有时从头开始重写一些东西更容易。这个“可怕的代码”是按预期工作还是充满了错误?有记录吗?

在我目前的项目中,几乎完全删除我前任的工作,然后从头开始重写,是最有效的方法。诚然,这是代码混淆、完全缺乏有意义的注释和完全无能的极端案例,因此您的里程可能会有所不同。

于 2010-03-21T21:30:24.093 回答
0

尽管一些遗留代码可能几乎无法理解,但仍然可以逐步重构并提高其易读性。你看过 Joshua Kerievsky 的Refactoring To Patterns一书吗?——这点很好。

于 2012-01-25T23:11:15.033 回答