views:

465

answers:

9

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?

+11  A: 

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
+1 for mentioning WELC, an amazing resource for dealing with the real world.
gooli
+2  A: 

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
Actually, creating an object with 97 fields sounds pretty scary as well.
gooli
@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
+9  A: 

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

Developer Art
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
eh, sorry about that. I looked for duplicates before posting but didn't find the one you are referring too
Yoni
+3  A: 

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
A: 

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
+4  A: 

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
A: 

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
+3  A: 

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
Obligatory +1 for mentioning the deity
Mawg
A: 

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 L.