当前位置:  开发笔记 > 编程语言 > 正文

有多少参数太多了?

如何解决《有多少参数太多了?》经验,为你挑选了19个好方法。

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

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

细心的程序员避免捆绑数据,这在逻辑上是必要的.

因此,如果您的例程有太多参数或使用结构来伪装一个大参数列表,那么您可能做错了.也就是说,你没有保持松耦合.

我的问题是,我什么时候可以考虑参数列表太大?我认为超过5个参数,太多了.你怎么看?



1> Nick..:

尽管第一修正案保证言论自由,但什么时候被认为是如此淫秽以至于可以受到监管?据波特斯图尔特大法官说,"当我看到它时,我就知道了." 这同样适用于此.

我讨厌制定像这样的硬性规则,因为答案的变化不仅取决于项目的规模和范围,而且我认为它甚至会改变到模块级别.根据你的方法正在做什么,或者类应该代表什么,很可能2个参数太多,并且是过多耦合的症状.

我建议通过首先提出问题,并像你一样对你的问题进行鉴定,你真的知道所有这一切.这里最好的解决方案不是依赖于一个快速而快速的数字,而是在同行中寻找设计评论和代码评审,以确定您具有低内聚和紧耦合的区域.

永远不要害怕向同事展示你的工作.如果你害怕,这可能是你的代码出现问题的更大迹象,而且你已经知道了.



2> Skizz..:

如果某些参数是冗余的,则函数只能有太多参数.如果使用了所有参数,则该函数必须具有正确数量的参数.拿这个经常使用的功能:

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个),并且还有从类名派生的参数.你会如何减少这个?你想减少更多的数字吗?

不要让参数的数量打扰你,只要确保它是合乎逻辑的,并且记录良好,让intellisense *帮助你.

*其他编码助手可用!


我正在投票.我对所有其他答案都说"3"和"4"感到惊讶!正确的答案是:必要的最低限度,有时可能是相当多的.
这是C**和**winapi.我想不出一个更糟糕的例子.
不,不.这是程序风格.Windows是对象,所以现在这是obsolette.今天,这将通过聚合类来解决,而不是通过一堆参数来解决.好的设计的直观规则是*如果你不能在一个简单的句子中描述功能(包括参数),它的设计很差*.我相信情况就是这样.
如果今天设计的功能可能看起来有点不同.x,y,nWidth和nHeight可以捆绑在Rectangle对象中.style和xStyle可以组合成一组枚举或字符串.现在你只有8个参数.
@finnw如果这个功能是今天设计的?它已经重新设计.表格f =新表格(); 有0个参数.
伙计们,不要忘记:这段代码可能是在1987年左右编写的,之前面向对象编程的东西在UI中很常见.虽然OOP没有像Core i5那样拖拽系统,但我们正在谈论像286这样的系统.
@Nick猜猜f.show()里面叫什么?:)容易包装这些东西,让它变得温暖和可爱.
这段代码来自古代书呆子自豪地制作混淆代码.甚至函数的名称都很糟糕:*Ex*是什么意思?独家,执行,排除,例外?如果这是好的设计,则不会创建MFC或.NET.

3> Patrick McEl..:

在清洁法典中,罗伯特C.马丁为这个主题专门写了四页.这是要点:

函数的理想参数数量为零(niladic).接下来是一个(monadic),紧接着是两个(二元).应尽可能避免三个论点(三元论).超过三个(polyadic)需要非常特殊的理由 - 然后不应该使用.


此外,马丁应该与C++标准委员会谈谈.的一半需要超过3个参数,因为只有一个迭代器范围已经是2.这只是使用迭代器编程的本质(即使用STL集合进行通用编程).
@SteveJessop:的错误在于它始终在切片上工作.如果要重新设计算法和集合,我会使算法总是采用整个集合,并且您将获得一种切片集合视图的方法,以允许算法处理部件; 或者我也会定义一个速记覆盖,以便在常见情况下轻松工作.
@LieRyan:如果我重新设计``,我会让它作用于范围对象.集合将是范围,但并非所有范围都是集合.事实上,助推已经做到了.无论如何,我的观点是,一个大量广泛使用的库忽略了这个建议,所以如果你这样做,那么*保证*发生在你身上的最糟糕的是,你的数百万用户中的许多用户会对你的界面进行微小的简化;-)
我怀疑它包含"this",因为这是执行的背景.在函数式编程中,上下文是全局的,在oop中,上下文是您应用该方法的对象.另外,如果你在参数列表中包含"this",那么就不可能有0个参数(理想值).

4> Jeffrey L Wh..:

我过去使用的一些代码使用全局变量只是为了避免传递太多参数.

请不要那样做!

(平时).



5> Rob Walker..:

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



6> Auron..:

非常感谢您的所有答案:

找到那些也认为(就像我一样)5个参数对代码的健全性有很好限制的人来说有点令人惊讶.

一般来说,人们倾向于同意3到4之间的限制是很好的经验法则.这是合理的,因为人们通常计算超过4件事情的时间不好.

正如米兰指出的那样,平均而言,人们可以一次保持或多或少的7件事情.但我认为你不能忘记,当你设计/维护/研究一个例程时,你必须记住更多的东西,而不仅仅是参数.

有些人认为例程应该有尽可能多的参数.我同意,但仅限于几个特定情况(调用OS API,优化很重要的例程等).我建议尽可能在这些调用之上添加一层抽象来隐藏这些例程的复杂性.

尼克对此有一些有趣的想法.如果您不想阅读他的评论,我总结一下:简而言之,这取决于:

我讨厌制定像这样的硬性规则,因为答案的变化不仅取决于项目的规模和范围,而且我认为它甚至会改变到模块级别.根据你的方法正在做什么,或者类应该代表什么,很可能2个参数太多,并且是过多耦合的症状.

这里的道德是不要害怕向同行展示你的代码,与他们讨论并试图"找出你内聚力低,紧密耦合的区域".

最后,我认为Wnoise非常赞同Nick,并总结了他对编程艺术的这种诗意愿景(见下文评论)的讽刺性贡献:

编程不是工程.代码组织是一门艺术,因为它取决于人为因素,这些因素过于依赖任何硬性规则的背景.



7> Bill K..:

这个答案假设一个OO语言.如果你没有使用它 - 跳过这个答案(换句话说,这不是一个与语言无关的答案.

如果你传递的参数超过3个(特别是内在类型/对象),那不是"太多",而是你可能错过了创建新对象的机会.

查找传递给多个方法的参数组 - 即使传递给两个方法的组几乎保证您应该在那里有一个新对象.

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



8> John Mulder..:

似乎有其他考虑而不仅仅是数字,这里有一些想到的:

    与功能与一次性设置的主要目的的逻辑关系

    如果它们只是环境标志,捆绑可以非常方便



9> Peter S. Hou..:

Alan Perlis着名的编程语言之一(在ACM SIGPLAN Notices 17(9),1982年9月中叙述)指出"如果你有一个包含10个参数的程序,你可能会错过一些."



10> Paul Reiners..:

根据Code Complete中的 Steve McConnell ,您应该这样做

将例程参数的数量限制为大约7


/:表示该factoid组成的数字:https://xkcd.com/899/

11> Learning..:

对我来说,当列表在我的IDE上越过一行时,它的一个参数太多了.我希望在一行中看到所有参数而不会破坏目光接触.但这只是我个人的偏好.


我可以向您介绍"回车"吗?
如果其他人给了类可笑的长名字,我就不会让我影响我如何定义或调用我的例程.
当列表与IDE上的一行相交时,您的显示器太小而无法使用该代码,您应该明确购买具有更高水平分辨率的显示器.换行或减少参数的数量只是解决根本问题的解决方法,即您的监视器对于该代码库来说太小了!

12> Inisheer..:

我普遍同意5,但是,如果我需要更多的情况,这是解决问题的最明确的方法,那么我会使用更多.



13> Mike Clark..:

短期记忆中的七件事?

    功能名称

    函数的返回值

    功能的目的

    参数1

    参数2

    参数3

    参数4


8.参数顺序

14> medopal..:

在Worst 5 Code Snippets中,检查第二个,"这是一个构造函数".它有超过37⋅4≈150参数:

在这里,程序员编写了这个构造函数[...]你可能认为它是一个很大的构造函数,但是他使用了eclipse自动代码生成工具[.] NOO,在这个构造函数中有一个我发现的小bug,这让我得出结论,这个构造函数是手工编写的.(顺便说一句,这只是构造函数的顶部,它不完整).

具有超过150个参数的构造函数



15> Kirk Strause..:

一个不必要的.我并不是说要搞笑,但有一些功能必然需要很多选择.例如:

void *
mmap(void *addr, size_t len, int prot, int flags, int fildes, off_t offset);

共有6个论点,每个论点都是必不可少的.此外,它们之间没有共同的联系来证明捆绑它们的合理性.也许你可以定义"struct mmapargs",但这会更糟.



16> Adam Bellair..:

根据Perl Best Practices,3可以,4太多了.这只是一个指导方针,但在我们的商店里,这是我们努力坚持的.



17> Kip..:

我自己在5个参数中绘制了公共函数的限制.

恕我直言,长参数列表仅在私有/本地助手函数中可接受,这些函数仅用于从代码中的几个特定位置调用.在这些情况下,您可能需要传递大量的状态信息,但可读性并不是一个大问题,因为只有您(或将维护您的代码并且应该了解模块基础知识的人)必须关心调用那个函数.



18> Onorio Caten..:

您应该考虑的一个相关问题是例行公事的凝聚力.大量的参数可能是一种气味,告诉你例程本身正在试图做太多,因此它的凝聚力是可疑的.我同意很难和快速数量的参数可能是不可能的,但我猜想高内聚程序会意味着参数数量很少.



19> Johan - rein..:

97听起来恰到好处.

任何更少,你失去灵活性.

推荐阅读
N个小灰流_701
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有