例程可以有参数,这不是新闻。您可以根据需要定义任意多的参数,但是过多的参数会使您的例程难以理解和维护。

当然,您可以使用结构化变量作为解决方法:将所有这些变量放在单个结构中并将其传递给例程。事实上,使用结构来简化参数列表是Steve McConnell在Code Complete中描述的技术之一。但正如他所说:

谨慎的程序员避免将数据捆绑在一起,除非逻辑上是必要的。

因此,如果你的例程有太多的参数,或者你使用一个结构体来掩盖一个大的参数列表,你可能做错了什么。也就是说,你没有保持耦合松散。

我的问题是,什么时候我可以认为一个参数列表太大?我认为5个以上的参数太多了。你怎么看?


当前回答

只有在某些参数是冗余的情况下,函数才可能有过多的参数。如果使用了所有参数,则函数必须具有正确的参数数量。以这个常用的函数为例:

HWND CreateWindowEx
(
  DWORD dwExStyle,
  LPCTSTR lpClassName,
  LPCTSTR lpWindowName,
  DWORD dwStyle,
  int x,
  int y,
  int nWidth,
  int nHeight,
  HWND hWndParent,
  HMENU hMenu,
  HINSTANCE hInstance,
  LPVOID lpParam
);

这是12个参数(如果将x,y,w和h捆绑为一个矩形,则为9个),还有从类名派生的参数。你将如何减少这种情况?你想把数字减少到更精确的程度吗?

不要让参数的数量困扰你,只要确保它是合乎逻辑的,并有良好的文档记录,让智能感知*帮助你。

*其他编码助手可用!

其他回答

I agree with Robert Martin's quote in Clean Code (as cited above): the fewer parameters the better. More than 5-7 parameters and method calls become pretty hard to comprehend. Things get especially bad if some of the parameters are optional (and so take null values), or if all the parameters have the same type (making it even harder to figure out which parameter is which). If you can bundle parameters into cohesive domain objects like Customer and Account, your code will be much more pleasant to work with.

有一个极端的情况:如果你有一个方法调用,它接受一个可变数量的参数,这些参数形成一个逻辑集,有更多的参数会有更少的认知开销。例如,您可能需要一个方法,以重试之间的毫秒数来指定HTTP请求重试次数。可以指定以1s、2s和3s为间隔的三次重试:

retries(1000, 2000, 3000)

在这种有限的情况下,向调用中添加更多参数并不会增加太多的精神负荷。

另一个需要考虑的问题是,您的语言是否支持命名参数列表并允许省略可选参数。较大的已命名参数列表比较大的未命名参数列表更容易理解。

但我还是宁可选择更少的参数,而不是更多的参数。

我的答案将基于函数被调用的频率。

如果它是一个只被调用一次的init函数,那么就让它占用10个parms或更多,谁在乎呢。

如果它每帧被调用一堆次,那么我倾向于创建一个结构,并只传递一个指针给它,因为这往往更快(假设你不是每次都重建结构)。

根据Perl最佳实践,3个是可以的,4个太多了。这只是一个指导方针,但在我们店里,这是我们努力遵守的。

我的经验法则是,我需要能够长时间地记住参数,以便查看调用并判断它做了什么。如果我不能看这个方法然后翻到一个方法的调用记住哪个参数是做什么的那就太多了。

对我来说,大约等于5,但我没有那么聪明。你的里程可能会有所不同。

您可以创建一个带有属性的对象来保存参数,并在超出设置的任何限制时将其传入。参见Martin Fowler的《重构》一书和简化方法调用的章节。

这个答案假设使用面向对象语言。如果你不使用,跳过这个答案(换句话说,这不是一个语言不可知的答案。

如果你传递了超过3个左右的参数(特别是内在类型/对象),这并不是“太多”,而是你可能错过了创建一个新对象的机会。

寻找传递给多个方法的参数组——即使是传递给两个方法的参数组也几乎可以保证在那里有一个新对象。

然后,您将功能重构到新对象中,您无法相信它对代码和对OO编程的理解有多大帮助。