所以我们在项目中有这个巨大的mainmodule.cpp源文件(11000行很大吗?),每次我不得不触摸它时,我都会畏缩。

由于这个文件是如此的核心和大,它不断积累越来越多的代码,我想不出一个好方法来让它实际上开始缩小。

该文件在我们产品的几个(> 10)维护版本中被使用和积极更改,因此很难重构它。如果我“简单地”将其拆分为3个文件,那么从维护版本合并回更改将成为一场噩梦。而且,如果您拆分具有如此长而丰富历史的文件,跟踪和检查SCC历史中的旧更改突然变得非常困难。

这个文件基本上包含了我们程序的“主类”(主要的内部工作调度和协调),所以每次添加一个特性,它也会影响这个文件,每次它的增长。:-(

在这种情况下你会怎么做?关于如何在不打乱SCC工作流程的情况下将新特性移动到单独的源文件中,您有什么想法吗?

(注意:我们使用c++和Visual Studio;我们使用AccuRev作为SCC,但我认为SCC的类型在这里并不重要;我们使用Araxis Merge来做实际的文件比较和合并)


当前回答

这是一个经典的例子,一个已知的反设计模式,称为blob。花点时间阅读我在这里指出的文章,也许你会发现一些有用的东西。此外,如果这个项目像它看起来的那样大,您应该考虑一些设计来防止发展成您无法控制的代码。

其他回答

永远不要再碰这个文件和代码! 对待就像你被困住了一样。开始为编码在那里的功能编写适配器。 用不同的单元编写新代码,只与封装怪物功能的适配器对话。 ... 如果以上只有一项是不可能的,那就辞职去找一份新工作。

下面是我所想到的解决这些问题的唯一办法。所述方法的实际增益是演化的累进性。这里没有革命,否则你很快就会陷入麻烦。

在原来的主类上面插入一个新的cpp类。目前,它基本上会将所有调用重定向到当前的主类,但目标是使这个新类的API尽可能清晰和简洁。

一旦完成了这些,就可以在新类中添加新功能。

至于现有的功能,当它们变得足够稳定时,您必须逐步将它们移动到新的类中。对于这段代码,您将失去SCC帮助,但是对此没有太多办法。只要选择合适的时机。

我知道这并不完美,但我希望它能有所帮助,这个过程必须适应您的需要!

额外的信息

注意,Git是一个SCC,它可以从一个文件跟踪代码片段到另一个文件。我听说过关于它的好东西,所以它可以帮助你逐步转移你的工作。

Git是围绕blob的概念构建的,如果我理解正确的话,blob表示代码文件的片段。在不同的文件中移动这些片段,Git会找到它们,即使您修改了它们。除了下面评论中提到的Linus Torvalds的视频之外,我还没有找到关于这个问题的一些清楚的东西。

这个问题在“有效地使用遗留代码”(http://www.amazon.com/Working-Effectively-Legacy-Michael-Feathers/dp/0131177052)一书的其中一章中得到了解决。

考虑以更合理的方式重写整个应用程序的方法。也许可以重写其中的一小部分作为原型,看看你的想法是否可行。

如果您已经确定了一个可行的解决方案,那么相应地重构应用程序。

如果所有产生更合理架构的尝试都失败了,那么至少您知道解决方案可能是重新定义程序的功能。

合并不会像将来获得30000个LOC文件那样是一个大噩梦。所以:

停止向该文件添加更多代码。 把它。


如果你不能在重构过程中停止编码,你可以暂时保留这个大文件,至少不向它添加更多的代码:因为它包含一个“主类”,你可以从它继承,并将继承的带有重载函数的类保留在几个新的小而设计良好的文件中。