函数参数已经改变:如何重构代码,尽可能少地改变

时间:2012-10-25 08:12:39

标签: c++ refactoring

有一个C ++函数可以计算某些东西(我不确定C ++在这里是否很重要,无论如何......)。它被称为50或更多的地方。现在事实证明这个功能错误地工作。为了正常工作,还需要三个参数。

如何根据必要的更改和紧凑性来最有效地重构此代码。

BTW新添加的参数是这样的,它们的默认值是不合理的。它们应该总是传递给函数。

很多人都在问一个例子。这是:

//old syntax of function
int f(int a1, int a2)
{
    return a + b;
}

//new syntax of function
int f(int a1, int a2, int a3, int a4, int a5)
{
    if (a3 == 10)
    {
        return a1 + a2;
    }
    else
    {
        return a1 + a2 + a4 + a5;
    }
}

此示例有帮助吗?我需要一种方法,使用一般方法,如设计模式,如重构原则,但不是一个特定的例子......

2 个答案:

答案 0 :(得分:4)

您可以为这3个参数定义默认值,您只需要更改它们必须的位置。或者在整个项目中使用IDE中的find并更正它们。

答案 1 :(得分:1)

这实际上取决于三个论点的来源。如果我们不能拥有默认值并且无法为额外参数创建公共模式,那么您可能别无选择,只能攻击组中的50个调用中的每一个。在这种情况下,您将保留原始呼叫并使用稍微不同的名称进行直接复制。然后逐渐移动,以便最终所有调用都使用额外参数调用新函数。然后你可以退休旧的。

另一方面,如果我们可以从默认值开始或至少使它们独立于调用代码,那么以下可能是一个好的计划。要记住的是,作为一个大的变化,这可能必须分阶段完成,以控制出现任何问题时的潜在影响。

首先,我会将函数的名称从xxxx更改为xxxx_<tag>,其中<tag>是更改的句柄 - 可能是来自缺陷跟踪器或更改管理系统的错误# 。然后我创建一个名为xxxx的新函数,只需调用xxxx_<tag>重新编译所有内容。到目前为止一切顺利:

void xxxx_tag(int p1, int p2)
{
    // ....
}

void xxxx(int p1, int p2)
{
    xxxx_tag(p1, p2);
}

接下来,我将更改xxxx_<tag>的签名,以添加额外的三个参数和对它的调用。现在我再次重建:

void xxxx_tag(int p1, int p2, int p3, int p4, int p5)
{
    // ....
}

void xxxx(int p1, int p2)
{
    // XXX, YYY, and ZZZ and constants or at least can be derived at this point.
    xxxx_tag(p1, p2, XXX, YYY, ZZZ);
}

这里的关键点还在于为将来的维护者添加注释,说明为什么这个包装器存在。不幸的是,这是因为其中一些变化会导致代码被遗忘,目的不明显。

然后,我会计划分五组或五组进行50次更改,以便将原始呼叫更改为新呼叫:

xxxx(p1, p2);

变为:

xxxx_tag(p1, p2, p3, p4, p5);

调用代码的每个部分都可以单独测试,以便您感到高兴(a)它像往常一样(即完全向后兼容)和(b)它修复了任何问题。

最后,完成所有这些操作后,您可以执行一次更改以删除新功能xxxx()并将xxxx_<tag>重命名为xxxx同样,您必须完全重建并测试。

<强>结论

无论你走哪条路,我都建议:

  1. 分阶段进行 - 这可以最大限度地减少出错的风险。
  2. 再次进行测试,测试和测试 - 这样可以减少您遇到问题的风险。