47

When debugging some web-service client code today (in Java, with jax-ws) I ran across a web-service method with the mind-blowing amount of 97 parameters!

I had to create a test case that calls this method, and I noticed several things:

  • code assist/hover doesn't scale well. I am using Eclipse, and the tooltip over the method is as wide as the screen and spans several lines.
  • I had to copy parameters values from a previous xml capture, and it was practically impossible to remember "where am I" - when I had the cursor located after a comma and before typing some value, I often got the data type wrong - I typed an Integer instead of a String and vice versa.
  • Even after I wrote all the parameters, I still had some errors and the signature didn't match. Unfortunately Eclipse marks the whole line in red as having an error, so finding where the mistake was took even more time :(

So this got me thinking, what do you think is the maximum sane number of parameters for a method? And if you could change this web-service signature, how do you think it can be improved?

Péter Török
  • 114,404
  • 31
  • 268
  • 329
Yoni
  • 10,171
  • 9
  • 55
  • 72
  • 4
    Pass a dict of paramter names/values instead? – pisswillis Feb 11 '10 at 14:07
  • 2
    @pisswillis, I thought of that, maybe it is useful for regular methods, but with web-service it undermines the whole point of the contract. You also get into problems of how to serialize the dict to xml, and your data model becomes much more relaxed (the dict can have missing values, etc.). – Yoni Feb 11 '10 at 14:09
  • The best thing is to pass a strongly typed dataset. Then the contract is in and kicking. – Stefan Feb 11 '10 at 14:12
  • 23
    97 params!? Sounds like a daily WTF. – Finglas Feb 11 '10 at 14:19
  • http://stackoverflow.com/questions/174968/how-many-parameters-are-too-many – Jørn Schou-Rode Feb 11 '10 at 14:20
  • Btw, you say it's Java but tag in language-agnostic, so I will take the liberty of giving a C idea (and hope that it can be used in other languages. First, of course, use CONST where possibly & meaningful, don't leave it open to doubt. Although it usually possible to tell if a param is input, output only and in/out (modified by function) are not so easy to spot, so I generally #define INPUT OUTPUT and MODIFY to be empty strings and use one before each parameter to make it immediately obvious to the reader. – Mawg says reinstate Monica Feb 12 '10 at 02:50
  • And it doesn't hurt to have a coding standard. Say, all input params first, then those that are in/out and finally output only. – Mawg says reinstate Monica Feb 12 '10 at 02:50
  • 97 is excessive and a better object model may help but this is a web service where single calls are encouraged. That being said, I would bet that the method is probably doing way too much. – Austin Salonen Feb 12 '10 at 17:37
  • An alternate implementation is to break it down into `RESTful` calls http://www.xfront.com/REST-Web-Services.html – John K Feb 14 '10 at 02:47
  • 5
    97?! Don't change it, and apply for guinness book of records! – rpattabi Nov 27 '10 at 11:53
  • 3
    @ragu.pattabi: Not a record: http://stackoverflow.com/questions/174968/how-many-parameters-are-too-many/2361645#2361645. – Mechanical snail Aug 19 '12 at 01:32
  • @Mechanical snail: OMG! How can anyone do such a thing! – rpattabi Aug 19 '12 at 14:21
  • I bet the project has been a Cobol project and they are rewriting it in Java. – zardosht May 11 '14 at 17:16

9 Answers9

82

There is no clear limit, but I am uncomfortable with more than 3-4 parameters. AFAIR Uncle Bob Martin in Clean Code recommends max 3.

There are several refactorings to reduce the number of method parameters (see Working Effectively with Legacy Code, by Michael Feathers for details). These come to my mind:

  • encapsulate many related parameters into a single object (e.g. instead of String surName, String firstName, String streetAddress, String phoneNumber pass a Person object containing these as fields)
  • pass parameters in the constructor or other method calls prior to the invocation of this method
Péter Török
  • 114,404
  • 31
  • 268
  • 329
  • 7
    +1 for mentioning WELC, an amazing resource for dealing with the real world. – elifiner Feb 11 '10 at 19:06
  • 11
    +1 for "no clear limit", because I think Uncle Bob's strict constraint of max. 3 parameters is too dogmatic. This can results in strange workarounds such as additional variables that hide dependencies and break thread safety (e.g. refactored PrimeGenerator.java on page 73 of "Clean Code"). – DaveFar Aug 28 '11 at 17:10
  • 2
    another +1 for WELC, it's a true gem. – Adam Adamaszek Nov 26 '12 at 11:24
44

When you have to ask, it is probably too many.

  • 2
    Essentially the same as the accepted answer in this exact duplicate question: http://stackoverflow.com/questions/174968/how-many-parameters-are-too-many – Jørn Schou-Rode Feb 11 '10 at 14:29
  • eh, sorry about that. I looked for duplicates before posting but didn't find the one you are referring too – Yoni Feb 11 '10 at 15:26
16

As Steve McConnell mentions in Code Complete, golden rule is 4 +/-3 parameters. For average human it's hard to remember more than 4 parameters, 5-7 should be used just in special cases and you should never use 8 or more.

Ondrej Slinták
  • 31,386
  • 20
  • 94
  • 126
8

Great Buddha!! Ninety-seven????

Good practise usually advises about max. six to eight. Of course, ymmv, and there may be a valid reason, from time to time, for a ninth. But 97??!!

A few thoughts ... are these simply data, or are decisions being made based on their values?

If many/most affect flow control you have an almost unmaintainable (even understandable, or testable) "design" (for small values of "design").

If they are simply data, can they be grouped into structures and pointers ot those structures passed?

Do you have any design documentation? Might that explain what is going on.

Oh, and, "Danger, Will Robinson" - anyone who will pass 97 parameters openly might also pass any number - not so obviously - as global variables.

P.s don't know how Eclipse works on Java, but with C/C++, if you put the paramaeters on separate lines

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

Eclipse will actually identify the line with the bad parameter

Mawg says reinstate Monica
  • 38,334
  • 103
  • 306
  • 551
5

Well, if you make it a JSON object, you can then wrap all 97 (or more) in that object and only send one object.

Mark Schultheiss
  • 32,614
  • 12
  • 69
  • 100
3

If its more than 5-10 parameters, then create an object that takes the parameters instead, it could be a typed dataset, structure or whatever.

Instead of :

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

Do:

Dim MyUser as new UserObject
MyUser.Firstname="Stefan"
...and so on...
MyWebservice.CreateUser(UserObject)
Stefan
  • 11,423
  • 8
  • 50
  • 75
  • 2
    Actually, creating an object with 97 fields sounds pretty scary as well. – elifiner Feb 11 '10 at 19:08
  • 2
    @gooli, yes. So you break it down in more sub objects that it conencted to the main object. street, country, zip fields as adress objects, phone and mailadresses as contact fields and so on. Its common sense in db-normalization and working with classes. ;) – Stefan Feb 12 '10 at 00:30
1

In my own experience, I've found that method signatures start getting confusing and hard to remember with more than 5 or 6 parameters. And once you get past 10 parameters it's just ridiculous.

These parameters really need to be combined into an object (or a small set of objects) which hold all the data. In the services I use, each service operation always takes a single Request object and returns a single Response object.

Kaleb Brasee
  • 51,193
  • 8
  • 108
  • 113
0

Well, I would suggest overloading the method so that you have simpler implementations of the method. This may be especially useful if many of the parameters rarely change and can be assigned defaults. However, if memory serves, I don't think you can overload a web service call (you have to use a distinct method name).

Another possible solution is to encapsulate the parameters into some kind of metadata class whose purpose is to hold the parameters. This would simplify the method signature. However, in some respects you're just offloading the problem to the parameter class. But, if the parameters can be catagorized into topics this technique may be employed by utilizing several metadata classes, each which would be included as a parameter to the web service. This should simplfy things and help you get your head around this monster.

Finally, it's hard to say without any details, but it certainly appears this code is a serious candidate for refactoring. I don't have a hard and fast rule on the number of parameters for a method other than to embrace the general principle of simplicity and readability.

Ed Chaparro
  • 313
  • 4
  • 13
0

As far as web services go, I prefer to handle paramaters as a single object. While your data contract may change, your serice contract won't. This makes your services more future proof.

For everything else, I am for 3 parameters and ocassionally go as high as 5.

John Laffoon
  • 2,885
  • 2
  • 26
  • 38