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

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

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

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

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

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


当前回答

一种不太危险的方法是对所有的线变化进行历史性的观察。有没有特定的函数比其他函数更稳定?可以说是变化的热点。

如果某一行在几年内没有被更改过,你可以将它移到另一个文件中,而不用太担心。我会看一下用最后一次修改注释的源代码,看看是否有任何函数可以提取出来。

其他回答

我想在这种情况下我该做的就是咬紧牙关

Figure out how I wanted to split the file up (based on the current development version) Put an administrative lock on the file ("Nobody touch mainmodule.cpp after 5pm Friday!!!" Spend your long weekend applying that change to the >10 maintenance versions (from oldest to newest), up to and including the current version. Delete mainmodule.cpp from all supported versions of the software. It's a new Age - there is no more mainmodule.cpp. Convince Management that you shouldn't be supporting more than one maintenance version of the software (at least without a big $$$ support contract). If each of your customers have their own unique version.... yeeeeeshhhh. I'd be adding compiler directives rather than trying to maintain 10+ forks.

跟踪文件的旧更改简单地通过您的第一个签入注释来解决,例如“从mainmodule.cpp分离”。如果你需要回顾最近的东西,大多数人会记得这个变化,如果是2年后,评论会告诉他们从哪里看。当然,回溯到2年前,看看是谁修改了代码以及为什么修改代码,这有多大价值呢?

你担心文件的大小。

从历史上看,C程序的文件大小是由机器PDP11/40的限制决定的。 我使用的这个可以处理最大4096字节的文件。为了解决这个问题 C编译器使用#include并发明了.h文件来帮助链接器和分段加载器,因为 加载器必须动态交换(因此在Intel架构中使用段寄存器)。

Small files solved the problem but left an historical legacy. Programmers now believe that small files are the only way to program. You have a machine with 4 gigabytes (vs 8 kilobytes on the 11/40). You have a machine with 3 billion instructions per second (vs 500 kilo instructions on the 11/40). You have a compiler that can block optimize code it can see (as opposed to linking .o files which it cannot see). You have a machine that is bandwidth limited by disk I/O but you want to create 500 tiny .c, .h, and .o files, possibly multiple times with the .h includes.

大的C文件绝对没有错。编译器可以大量优化 磁盘I/O最小,链接器时间消失,编辑器可以找到琐碎的东西 一个花哨的IDE,……

11000行对于今天来说是一个微不足道的文件。把自己从历史中解放出来。

好吧,我理解你的痛苦:)我也参与过一些这样的项目,它并不漂亮。这个问题没有简单的答案。

一种可行的方法是开始在所有函数中添加安全保护,也就是说,检查方法中的参数、前置/后置条件,然后最终添加单元测试,以便捕获源的当前功能。一旦你有了这些,你就可以更好地重构代码,因为如果你忘记了什么,你就会有断言和错误弹出来提醒你。

有时候,重构带来的痛苦可能会大于好处。那么,最好是让原始项目处于伪维护状态,从头开始,然后增量地添加野兽的功能。

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

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


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

Find some code in the file which is relatively stable (not changing fast, and doesn't vary much between branches) and could stand as an independent unit. Move this into its own file, and for that matter into its own class, in all branches. Because it's stable, this won't cause (many) "awkward" merges that have to be applied to a different file from the one they were originally made on, when you merge the change from one branch to another. Repeat. Find some code in the file which basically only applies to a small number of branches, and could stand alone. Doesn't matter whether it's changing fast or not, because of the small number of branches. Move this into its own classes and files. Repeat.

因此,我们去掉了到处都一样的代码,以及特定于某些分支的代码。

This leaves you with a nucleus of badly-managed code - it's needed everywhere, but it's different in every branch (and/or it changes constantly so that some branches are running behind others), and yet it's in a single file that you're unsuccessfully trying to merge between branches. Stop doing that. Branch the file permanently, perhaps by renaming it in each branch. It's not "main" any more, it's "main for configuration X". OK, so you lose the ability to apply the same change to multiple branches by merging, but this is in any case the core of code where merging doesn't work very well. If you're having to manually manage the merges anyway to deal with conflicts, then it's no loss to manually apply them independently on each branch.

我认为你说这种SCC无关紧要是错误的,因为例如git的合并能力可能比你正在使用的合并工具更好。因此,核心问题“合并困难”发生在不同scc的不同时期。但是,您不太可能更改scc,因此这个问题可能无关紧要。