1

我有一个由其他人编写的 3500 行长的 C 函数,我需要在不引起任何回归的情况下将其分解。由于它在 C 中,我面临的主要问题是维护变量的状态。例如,如果我将一小部分代码分解为另一个函数,我将需要传递 10 个参数。其中一些实际上会在新函数的代码中发生变化。所以有效地我需要向他们传递一个指针。它变得非常混乱。有没有更好的方法来处理这种重构?任何“最佳实践”?

4

6 回答 6

3
  • 每个函数都应该做一件通过检查代码很容易弄清楚的事情。
  • 与其传递 10 个变量,不如将它们放入一个结构中并传递。
于 2012-05-22T19:10:45.123 回答
3

单元测试。提取依赖于 3 个或更少变量(最好是 1 个变量)的代码的一小部分并对其进行测试。将原始函数中的代码替换为对新函数的调用。

于 2012-05-22T19:10:35.840 回答
2

在我看来,您能做的最好的事情就是彻底研究该功能,并充分了解其内部结构。这个函数很可能里面有很多反模式,所以我不会尝试重构它:一旦我知道它是如何工作的(我知道这可能需要很多时间)我会把它扔掉并从头开始重写所需的等效较小函数。

于 2012-05-22T19:13:55.847 回答
1

将在多个子函数之间共享的局部变量打包到一个结构中并传递结构?

于 2012-05-22T19:10:53.793 回答
1

你被C卡住了吗?我有时会将此类函数转换为 C++ 类,在其中我将部分(或全部)局部变量转换为成员变量。完成此步骤后,您可以轻松地将部分代码分解为处理成员变量的方法。

在实践中,这意味着这样的功能:

... do_xxx(...)
{
  .. some thousand lines of code...
}

可以转换为:

class xxx_handler
{
public:
  xxx_handler(...);
  ... run(...)
  {
    part1();
    part2();
    part3();
    return ...;
  }
private:
  // Member variables goes here.
};

// New replacement function.
... do_xxx(...)
{
  xxx_handler handler(...);
  return handler.run(...);
}
于 2012-05-22T19:36:55.273 回答
0

作为将函数的一部分作为独立函数取出的第一步,首先要做的事情是将“函数全局”临时变量移动到更紧密的范围内,例如:

int temp;

temp = 5;
while(temp > 0) {...}
... 
temp = open(...);
if (temp < 0) {...}

转换成

{
  int temp = 5;
  while(temp > 0) {...}
}
...
{
  int temp = open(...);
  if (temp < 0) {...}
}

之后,将每个{}块移动到一个单独的函数中会更容易,它会做一件定义明确的事情。

但是,在进行单元测试之后,最重要的指导方针是:使用支持“樱桃采摘”的版本控制(如git)。经常提交,基本上每当它在重构某些内容后编译时,然后在它实际工作时再次提交(或者如果您不想拥有第一个提交版本,则修改之前的提交)。学习使用版本控制的 diff 工具和樱桃采摘,当您需要在破坏某些内容后回滚时。

于 2012-11-23T11:49:09.240 回答