重构20K行库的技巧

时间:2010-12-29 20:28:16

标签: php oop open-source refactoring

我已经给马里奥的答案奖励了100分,但如果我看到新的好答案,我可能会开始第二个100分的奖励。这就是为什么我要保持这个问题的开放而不会选择尽管已经将奖金授予了马里奥,但最后的答案仍然存在。

这可能看起来像一个简单的问题(研究代码和重构),但我希望那些有更多经验的人可以给我一些可靠的建议。

该库是一个开源的20,000行库,它们都在一个文件中,我自己也没有写过。代码看起来写得很糟糕,单个文件甚至是一个更大的问题,因为它至少每次我想要进行更改时都会冻结eclipse半分钟,这也是我认为重构这个库的重要原因之一小班。

除了阅读代码并试图理解它之外,在重构像这样的库时,是否存在常见的(或不常见的)提示?你有什么建议让我的生活更轻松一点?

感谢大家的意见。

11 个答案:

答案 0 :(得分:42)

适用一些通用原则:

  1. 分而治之。将文件拆分为较小的逻辑库和功能分组。您将以这种方式了解有关库的更多信息,并使其更易于理解和逐步测试。

  2. 删除重复。寻找重复的功能和概念,并用标准库函数或库中的集中函数替换它们。

  3. 添加一致性。平滑参数和命名。

  4. 添加单元测试。这是重构库的最重要部分。使用jUnit(或类似的),并添加可用于验证函数是否正确以及它们是否未更改的测试。

  5. 添加文档。在编写测试时记录您对一致,改进的库的理解。

答案 1 :(得分:28)

如果代码写得不好,很可能会有很多克隆。找到并摆脱克隆可能会使其更易于维护以及减小其大小。

你可以找到各种克隆探测器,专门用于PHP:

在检测有趣克隆的质量不同的能力方面,排名最低至最能力的顺序(恕我直言,我个人对CloneDR的强烈兴趣)。

如果代码写得不好,很多可能已经死了。值得找出哪个部分在实践中执行,哪个部分不执行。即使没有测试(您只需手动锻炼程序),测试覆盖工具也可以让您很好地了解此问题的答案。测试覆盖工具所执行的内容显然并没有消失。什么不执行...可能值得进一步调查,看看你是否可以删除它。如另一个答案所示,测试覆盖工具对于告诉您单元测试执行了多少代码也很有用。最后,测试覆盖率工具可以帮助您找到其中的一些功能:从外部运行功能,以及测试覆盖工具所执行的任何代码都可能是相关的。

我们的PHP Test Coverage Tool可以收集测试覆盖率数据。

答案 2 :(得分:10)

如果它是一个开源库,请询问开发人员。首先,很可能某人已经(尝试过)重组后的版本。事实上,某些东西的大臃肿版本实际上是从更模块化的版本自动生成的。

我实际上有时会为我的一个严格插入的应用程序执行此操作,并允许使用简单的cat */*.php > monolithic.php,这样可以简化分发和处理。所以问那可能就是这种情况。

如果确实想重组它,请使用经过时间验证的增量扩展结构。通过隔离原始类,将类library拆分为多个文件。每隔约2000行拆分,并命名第一部分library0.php

 class library0 {
     var $var1,$var2,$var3,$var4;
     function method1();
     function method2();
     function method3();
     function method4();
     function method5();

接下来的部分很简单,并保留了接下来的几个方法:

 class library1 extends library0 {
     function method6();
     function method7();
     function method8();
     ...

这样做直到你将它们全部分开。使用真实姓名library.php调用最后一个文件,class library extends library52 {应该这样做。这是如此荒谬的简单化,正则表达式脚本应该能够做到。

现在显然,这里没有节省内存。然后把它拆分就像在结构化方面没有任何收获。然而,有了20000行,很难在第一时间获得快速概览和有意义的分组。因此,从任意重组开始,代替一个明显的计划。但是从那里开始你可以很好地排序并将最无用的代码放到最后一个文件中,并且只要它们足够就使用较轻的基类。但是,您需要一个依赖关系图表来查看这是否可行,否则错误可能会在运行时爆炸。

(我没有尝试过像这样的巨大项目这种方法。但任意将某些东西分成三部分,然后重新调整它以获得敏感性确实有效。那次。)

答案 3 :(得分:9)

  • 我假设您打算将图书馆分成主题相关的课程。绝对考虑使用autoloading。这是自切片面包以来最好的事情,并使相互依赖性易于处理。

  • 从一开始就使用phpDoc兼容的评论记录代码。

答案 4 :(得分:5)

一本很好的书,通过大量的例子和细节回答你的问题:Michael Feathers有效地使用遗产代码。

答案 5 :(得分:5)

呼叫侧方法

如果您知道库的使用仅限于特定的类,模块或项目,则可以更容易地从主叫方处理问题。然后,您可以执行以下操作来清理代码并重构代码。从呼叫方接近的一点是因为很少有人进入图书馆。调用的次数越多(可能)在lib中实际使用的代码越少。

编写主叫方测试

编写一个模拟对库完成的调用的测试。

埋葬死亡守则

如果有很多死代码,这将是一个巨大的胜利。跟踪对库的实际调用并删除其他所有内容。运行测试并验证。

重构是什么?

由于您有测试,因此重构(甚至替换)库中的代码应该更容易。然后,您可以应用标准重构规则 ie。 (重复数据删除,简化,整合等)

答案 6 :(得分:5)

除了已经说明的内容之外,我建议根据Martin Fowler's Catalog of Refactorings查看his book。该页面还包含大量additional sources,有助于了解应如何处理重构。可以在sourcemaking找到更详细的目录列表。请注意,并非所有这些技术和模式都可以应用于PHP代码。

还有很多有用的工具可以帮助您进行重构(一般情况下)http://phpqatools.org。使用这些来分析您的代码,以查找死代码或重复代码,高圈复杂度,经常执行的代码等等。这不仅可以让您更好地了解代码,还可以告诉您代码的哪些部分是关键的(最好在开头不要触及),哪些部分可能是重构代码。

无论你做什么,都要写单元测试。您必须确保在重构​​时不会破坏代码。如果库尚未经过单元测试,请在更改任何代码之前添加测试。如果您发现无法为要更改的部分代码编写测试,请检查在其他位置执行较小的重构是否可以让您更轻松地执行此操作。如果没有,请不要尝试重构。

答案 7 :(得分:5)

  1. 为图书馆编写测试 所有代码行都是 涵盖(即100%覆盖范围)。
  2. 使用     TDD。从更高的开始     级别模块和重新分数(Top to     底部方法)。
  3. 运行步骤1中提到的测试并验证步骤2的结果。
  4. 我理解100%覆盖率(如步骤1中所述)并不一定意味着所有功能都已被涵盖,至少我们确保无论当前系统的o / p与o / p相同p。新系统。

答案 8 :(得分:4)

首先,考虑使用不同的IDE - Eclipse在性能方面非常糟糕。科莫多的速度更快。 PhpStorm也是如此。

在使重构更容易的方面,我首先尝试确定高级图片 - 有什么功能?有课吗?你能把这些类放到单独的文件中吗?

答案 9 :(得分:1)

http://www.amazon.com/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882

重构取决于您的目标和解决方案类型。本书将帮助您理解正确代码的基本概念。

答案 10 :(得分:0)

通常,一般的经验法则是删除重复的代码。还要确保提供有用的文档。如果您使用的是Java,那么Javadoc非常有用,但其他语言也可以使用它。