这真的取决于这三个论点的来源。如果我们不能有默认值并且不可能为额外参数创建一个通用模式,那么您可能别无选择,只能分组攻击 50 个调用中的每一个。在这种情况下,您将保留原始调用并制作一个名称稍有不同的直接副本。然后您逐渐移动,以便最终所有调用都使用额外参数调用新函数。然后,您可以退休旧的。
另一方面,如果我们可以从默认值开始,或者至少使它们独立于调用代码,那么以下可能是一个不错的计划。需要牢记的是,作为一个巨大的变化,这可能必须分阶段进行,以控制出现任何问题时的潜在影响。
首先,我会将函数的名称从xxxx
wherexxxx_<tag>
更改<tag>
为更改句柄 - 可能是来自缺陷跟踪器或更改管理系统的 bug #。然后我会创建一个名为的新函数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 次更改,例如 5 或 10 组,以便您将原始呼叫更改为新呼叫:
xxxx(p1, p2);
变成:
xxxx_tag(p1, p2, p3, p4, p5);
调用代码的每个部分都可以单独测试,因此您很高兴(a)它像往常一样工作(即完全向后兼容)和(b)它修复了任何问题。
最后,一旦完成所有这些,您就可以进行一次更改以删除新功能xxxx()
并重命名xxxx_<tag>
为xxxx
Again,您必须完全重建和测试。
结论
无论你走哪条路,我都会推荐:
- 分阶段进行 - 这样可以最大限度地减少出错的风险。
- 测试,测试和测试 - 再次,这减少了您遇到问题的机会。