你如何重构一个庞大的混乱代码库?

Ric*_*ket 40 language-agnostic oop refactoring

我的代码很乱.不可否认,我自己写了一年 - 一年前.它没有得到很好的评论,但它也不是很复杂,所以我可以理解它 - 只是不足以知道从哪里开始重构它.

我违反了过去一年中我读过的所有规则.有些职责有多个职责,有间接访问(我忘记了这个术语 - 类似的东西foo.bar.doSomething()),就像我说的那样评论不好.最重要的是,它是游戏的开始,所以图形与数据耦合,或者我试图解耦图形和数据的地方,我制作数据public以便图形能够访问数据需要...

这是一个巨大的混乱!我从哪里开始?你会如何开始这样的事情?

我目前的方法是获取变量并将它们切换为私有,然后重构破坏的碎片,但这似乎不够.请建议其他策略来浏览这个烂摊子并把它变成干净的东西,以便我可以继续我离开的地方!


两天后更新:我一直在绘制类似UML的图表,并沿途捕捉一些"低挂水果".我甚至发现了一些代码是新功能的开始,但是当我试图减少一切时,我已经能够删除这些位并使项目感觉更清洁.在绑定我的测试用例之前,我可能会尽可能地进行重构(当然,只有那些100%肯定不影响功能的东西!),所以我不必重构测试用例.改变功能.(你认为我做得对吗,或者你认为,我更容易吸吮它并先写下测试吗?)

请投票选出最佳答案,以便我公平地标记!您也可以随意添加自己的答案,还有空间给您!我会再给它一天左右,然后可能将最高投票的答案标记为已接受.

感谢迄今为止做出回应的所有人!


2010年6月25日:我发现了一篇博文,它直接回答了那个似乎对编程有很好掌握的人的问题:(或者,如果你读了他的文章,可能不会:))

为此,当我需要重构代码时,我做了四件事:

  1. 确定代码的用途是什么
  2. 绘制所涉及的类的UML和动作图
  3. 四处寻找合适的设计模式
  4. 确定当前类和方法的更清晰的名称

Joh*_*ohn 19

给自己一份Martin Fowler的Refactoring.它有一些很好的建议来解决你的重构问题.大约75%的书是你可以做的小菜谱式重构步骤.它还提倡自动单元测试,您可以在每个步骤后运行,以证明您的代码仍然有效.

至于一个开始的地方,我会坐下来绘制你的程序的高级架构.你不必对详细的UML模型有所了解,但是一些基本的UML并不是一个坏主意.您需要全面了解主要部件如何组合在一起,以便您可以直观地看到您的去耦将要发生的位置.只需一两页基本的方框图就可以帮助您获得现在的压倒性感觉.

如果没有某种高级规范或设计,你只会冒险再次迷失,并最终导致另一个难以维持的混乱.

如果您需要从头开始,请记住,您从未真正从头开始.你有一些代码和你第一次获得的知识.但有时它确实有助于从一个空白项目开始并随时随地拉入内容,而不是在混乱的代码库中引发火灾.只要记住不要完全抛弃它,将其用于其良好的部件并随身携带它们.


Fab*_*eeg 16

在不同场合对我来说最重要的是单元测试:我花了几天时间为旧代码编写测试,然后我可以自信地重构.究竟是一个不同的问题,但通过测试,我可以对代码进行实质性的实质性更改.


Cow*_*wan 11

我将推荐每个人对Fowler 重构的建议,但在您的具体情况下,您可能希望看看Michael Feathers的" 有效使用遗留代码",这非常适合您的情况.

Feathers讨论了Characterization Tests,它是单元测试,不是为了断言系统的已知行为,而是为了探索和定义现有的(不清楚的)行为 - 在你编写自己的遗留代码并自己修复它的情况下,这个可能不是那么重要,但如果你的设计很草率,那么很可能有部分代码通过'魔术'工作并且他们的行为不清楚,甚至对你来说 - 在这种情况下,表征测试会有所帮助.

本书的一个重要部分是关于在代码库中查找(或创建)接缝的讨论- 如果您愿意,接缝是自然的"断层线",您可以闯入现有系统开始测试,并将其拉向更好的设计.很难解释,但值得一读.

一篇简短的论文,其中Feathers充实了本书中的一些概念,但它确实非常值得追捕整个事物.这是我的最爱之一.


Chr*_*per 5

你总是可以从"刮擦"开始.这并不意味着废弃它,而是从零开始,但是从一开始就尝试重新思考高级别的东西,因为自从你上一次工作以来你似乎学到了很多东西.

从更高的层次开始,当您构建新的和改进的结构的脚手架时,请采用您可以重用的所有代码,如果您愿意阅读它并进行一些小的更改,这可能比您想象的要多.

在进行更改时,请务必严格遵守您现在所知道的所有良好做法,因为您以后会真的感谢自己.

正确地重新制作程序以完成之前所做的事情,只有更"干净"才能令人惊讶地令人惊讶.;)

正如其他人所提到的,单元测试是你最好的朋友!它们可以帮助您确保重构工作,如果您从"刮擦"开始,那么它就是编写它们的最佳时机.


Tho*_*sen 5

只是一个比你想象的更重要的额外重构:正确命名!

这适用于任何变量名称和方法名称.如果名称没有准确反映出该用途的内容,则将其重命名为更准确的内容.这可能需要多次迭代.如果您找不到简短且完全准确的名称,那么该项目会做得太多,并且您有一个非常适合需要拆分的代码段.名称还清楚地表明了切割的位置.

另外,记录你的东西.每当答案为什么?如何通过答案清楚地传达出来?(作为代码)您需要添加一些文档.捕获设计决策可能是最重要的任务,因为在代码中很难做到.