通过不直接处理的中间方法传递相同的变量

Passing the same variable through intermediate methods which don't directly process it

提问人:Naci 提问时间:11/3/2016 更新时间:11/4/2016 访问量:52

问:

我经常发现自己将变量传递到一个方法中,在那里它没有直接使用,而是传递给另一个方法进行进一步处理。我也不知道这种做法是否有名字。我可以用示例代码更好地解释它:

static void main() {
    int a = method1(var1, var2, var3)
}

int method1(int var1, int var2, int var3) {
    var4 = some_function_of(var1, var2)
    return method2(var3, var4)
}

int method2(int var 3, int var4) {
    return some_other_function_of(var3, var4)
}

当相同的变量 (var3) 通过更长的方法链传递时,这种情况可以扩展。我认为这可能是一个不好的做法,因为在我的示例中,method1 是某种不操纵 var3 的中间体。在性能、设计和/或可读性方面有更好的做法吗?

算法 性能 语言无关 的可读性

评论

0赞 Paul R 11/3/2016
这个 AFAIK 没有名字,因为它只是正常的做法。它不会引起任何问题,除非您的参数数量很大,在这种情况下,是时候开始将它们捆绑到类或结构中了。
0赞 Shubham 11/3/2016
@PaulR 如果方法链很长,那么我们不应该将变量声明为全局变量吗?这会是一件好事吗?
2赞 Paul R 11/3/2016
@Shubham:全局变量通常是一个坏主意 - 它们破坏了模块化和解耦,可能不是线程安全的,并且会阻止某些编译器优化。此规则的例外情况往往是系统范围的全局变量,例如调试级别,但通常尽量避免全局变量。

答:

2赞 GhostCat 11/3/2016 #1

至少对于面向对象语言来说,答案是:

  1. 你肯定想避免这样的代码 - 因为你努力将你的参数列表减少到绝对最小值;目标是
  2. 如果你发现你的类应该提供各种方法,这些方法都需要“相同”的参数;而不是使该参数成为类中的候选字段。

在非 oo 语言中,我认为您必须在拥有更多函数和参数列表长度之间务实地取得平衡。在您的示例中,

static void main() {
  int var4 = some_function_of(var1, var2)
  int a = method2(var3, var4)
}

避免方法1 ...省去了将 var3 传递给第一个方法的时间。而且你仍然在“单层抽象”原则的规则范围内。

评论

0赞 Naci 11/5/2016
谢谢,我同意平衡模块化和参数长度列表的想法。我想这是一种设计选择。我有点松了一口气,因为这个一直困扰着我的问题没有一个明显而理想的答案
0赞 GhostCat 11/5/2016
如果 IT / 计算机科学中所有问题的一小部分都有明显而理想的答案......那我们就不会得到那么多的报酬了,不是吗。当然:不要忘记接受你喜欢的答案......我怀疑你会听到很多关于你的问题的其他信息(因为我认为你的标签没有引起太多关注)
1赞 Andrew 11/4/2016 #2

这并不少见,也不一定是坏做法。不过,它可能会影响您提到的所有三个指标:

  1. 性能:向函数调用添加另一个参数可能会导致性能下降,但并非总是如此。这取决于语言、编译器/解释器和平台。例如,针对 C++ 的优化编译器将尝试避免复制变量,即使它是按值传递的(有时它会完全消除函数调用)。但是,如果编译器不能很好地遵循路径,则通过多个函数传递值可能会扰乱编译器的优化。不过,我预计由此对性能的任何影响都是最小的。

  2. 设计:根据你的语言的范式(面向对象、函数式等),这可能表明你的设计可以改进,也许通过将数据封装在一个结构或类中,以便只传递一个参数(类实例指针),并且每个函数只访问它需要的类成员。

  3. 可读性:这不应该使单个函数更难阅读,因为它们不应该关心参数来自哪里,而且很明显参数正在传递给另一个函数。不过,这可能会使理解整个程序变得更加困难,因为如果值在被触及之前经过一长串调用,则很难跟踪它们的来源。

通常,最好最小化参数列表(出于所有这些原因),并使数据“更接近”需要它的代码。如果你做了这些事情,这个案例应该不会出现太多,当它出现时,它不太可能是由于糟糕的设计造成的。