当一个方法有太多参数?

时间:2010-02-11 14:01:14

标签: language-agnostic ide parameters

今天调试一些Web服务客户端代码时(使用Java,使用jax-ws)我遇到了令人兴奋的97个参数的Web服务方法!

我必须创建一个调用此方法的测试用例,我注意到了几件事:

  • 代码辅助/悬停不能很好地扩展。我正在使用Eclipse,并且该方法的工具提示与屏幕一样宽,并且跨越多行。
  • 我不得不从之前的xml捕获中复制参数值,而且几乎不可能记住“我在哪里” - 当我将光标放在逗号后面并且在键入一些值之前,我经常得到错误的数据类型 - 我键入了一个Integer而不是String,反之亦然。
  • 即使我写了所有参数,我仍然有一些错误,签名不匹配。不幸的是,Eclipse将整条线标记为红色,因为有错误,所以找出错误所花费的时间更多:(

所以这让我思考,您认为方法的最大参数数量是多少?如果您可以更改此Web服务签名,您认为如何改进它?

9 个答案:

答案 0 :(得分:64)

没有明确的限制,但我对超过3-4个参数感到不舒服。 Clean Code中的AFAIR叔叔Bob Martin建议最多3人。

有几种重构可以减少方法参数的数量(详见Michael Feathers的Working Effectively with Legacy Code)。我想到了这些:

  • 将许多相关参数封装到单个对象中(例如,而不是String surName, String firstName, String streetAddress, String phoneNumber传递包含这些字段作为字段的Person对象)
  • 在调用此方法之前在构造函数或其他方法调用中传递参数

答案 1 :(得分:34)

当你不得不问,它可能太多了。

答案 2 :(得分:12)

史蒂夫麦康奈尔在Code Complete中提到,黄金法则是4 +/- 3个参数。对于普通人来说,很难记住4个以上的参数,只有在特殊情况下才能使用5-7,你永远不应该使用8个或更多。

答案 3 :(得分:8)

大佛!!九十七????

良好做法通常建议最多。六到八个。当然,ymmv,可能有一个有效的理由,不时,为第九。但97 ?? !!

一些想法......这些只是数据,还是基于价值观做出的决定?

如果许多/大多数影响流量控制,您将拥有几乎无法维护(甚至可以理解或可测试)的“设计”(对于“设计”的小值)。

如果它们只是数据,它们是否可以分组成结构和指针,通过这些结构?

你有设计文件吗?可能会解释发生了什么。

哦,而且,“危险,威尔罗宾逊” - 任何公开传递97个参数的人也可以传递任何数字 - 不是那么明显 - 作为全局变量。

P.s不知道Eclipse是如何在Java上工作的,但是如果你把paramaeters放在不同的行上,那么使用C / C ++

char DoEverything(
        int meaninglessParameterName1,
        char *meaninglessParameterName2,
        ....
        long double *meaninglessParameterName97)
        { return !NULL;}

Eclipse实际上会识别带有错误参数的行

答案 4 :(得分:5)

好吧,如果你把它变成一个JSON对象,你就可以将所有97个(或更多)包装在该对象中,只发送一个对象。

答案 5 :(得分:3)

如果超过5-10个参数,则创建一个取代参数的对象,它可以是一个类型化的数据集,结构或其他。

而不是:

Mywebservice.CreateUser(Firstname, LastName, Age,Sex, Haircolor,AmountOfFingers,AmountOfTeeht,Childrens,,,,,,,,,,,,,and so on)

执行:

Dim MyUser as new UserObject
MyUser.Firstname="Stefan"
...and so on...
MyWebservice.CreateUser(UserObject)

答案 6 :(得分:1)

根据我自己的经验,我发现方法签名开始变得混乱,难以记住超过5或6个参数。一旦你超过10个参数,这就太荒谬了。

这些参数确实需要组合成一个包含所有数据的对象(或一小组对象)。在我使用的服务中,每个服务操作总是占用一个Request对象并返回一个Response对象。

答案 7 :(得分:0)

好吧,我建议重载方法,以便您可以更简单地实现该方法。如果许多参数很少更改并且可以指定默认值,这可能特别有用。但是,如果内存服务,我认为你不能重载Web服务调用(你必须使用不同的方法名称)。

另一种可能的解决方案是将参数封装到某种元数据类中,其目的是保存参数。这将简化方法签名。但是,在某些方面,您只是将问题卸载到参数类。但是,如果参数可以被分类为主题,则可以通过利用若干元数据类来使用该技术,每个元数据类将被包括作为web服务的参数。这应该是简单的事情,并帮助你了解这个怪物。

最后,没有任何细节很难说,但看起来这个代码肯定是重构的一个重要候选人。除了采用简单性和可读性的一般原则之外,我对方法的参数数量没有严格的规则。

答案 8 :(得分:0)

就Web服务而言,我更喜欢将参数作为单个对象处理。虽然您的数据合同可能会发生变化,但您的服务合同却不会。这使您的服务更具前瞻性。

对于其他一切,我是3个参数,偶尔会高达5个。