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

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

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

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

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


当前回答

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)

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

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

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

其他回答

似乎除了数字之外还有其他的考虑因素,以下是我想到的一些:

与函数主要目的的逻辑关系vs.一次性设置 如果它们只是环境标志,那么捆绑会非常方便

如果您开始在心里计算签名中的参数,并将它们与调用匹配,那么是时候重构了!

97听起来差不多。

少了一点,你就失去了灵活性。

在我看来,使用长参数列表的理由是数据或上下文本质上是动态的,想想printf();一个使用可变参数的好例子。处理这种情况的一个更好的方法是通过传递一个流或xml结构,这再次减少了参数的数量。

一台机器当然不会介意大量的参数,但是开发人员也会考虑维护开销、单元测试用例和验证检查的数量。设计师也讨厌冗长的参数列表,更多的参数意味着对接口定义的更多更改,无论何时要进行更改。关于耦合/内聚的问题来自以上几个方面。

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

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个),还有从类名派生的参数。你将如何减少这种情况?你想把数字减少到更精确的程度吗?

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

*其他编码助手可用!