tags:

views:

147

answers:

7

Often time methods take more than 3 parameters which are all of the same type, eg.

void mymethod (String param1, String param2, String param3)

then it's very easy for the client to mix up the parameters orders, for instance inverting param1 and param2:

mymethod (param2, param1, param3);

...which can be the cause of much time spent debugging what should be a trivial matter. Any tips on how to avoid this sort of mistake (apart from unit tests) ?

A: 

In other languages which support them, using named parameters is the obvious way to deal with this. http://www.artima.com/weblogs/viewpost.jsp?thread=118828 has some tips, including a way to provide fake named parameters within Java.

crazyscot
A: 

If your method takes more than 4 parameters then you got an ugly API.

Why are all your parameter types Strings. Does it make sense to create classes to represent those String like values, instead of just using String for everthing.

For example use a Name class rather String, so creating a Person might look like this...

Person create( FirstName firstName, LastName lastName, Address address );   

Often programs use String as a container for all sorts of data, whcih leads to poor programs that rarely validate their data. By creating specialist classes even if they hold a single String property, one can add some validation to the factory and know for sure that its a valid value. Naturally your string containers should also be immutable - getters only no setters.

Take a look at Java Puzzlers from Josh Bloch to learn more tips and wisdom.

mP
In your example it would be even better to use a Name class with the properties FirstName and LastName, removing the need for one parameter... which is (i think) exactly what you try to explain.
dbemerlin
Not really. Lots of small classes is better than large do everything classes. When creating a family of Persons its better to create the LastName once and pass it too each created Persons. That means that the last name only needs to be validated once, rather than once for each member of the family. If someone in the family has a different last name then naturally one would create another LastName.
mP
There may be times also that a Person has multiple given names which are each represented by an instance of FirstName. Perhaps in this case GivenName would be a better class name. Either way the principal applies by keeping our classes small and simple we can bundle them together to build larger more useful composite classes. From my further example its fairly obvious that my proposal is infinitely better and more extensible.
mP
+7  A: 

You are searching for: Named Parameter idiom in java

volothamp
This crap, a series of lots of String parameters is not type safe as its very easy to transpose the wrong parameter in the wrong place. Look at my answer for a better example. In this particular case the compiler can help you note mistakes because one puts the wrong type parameter in the wrong place. Use it...
mP
i agree with mP, named parameters are imho only suitable if a method has several optional parameter combinations (which often means that there should be multiple methods or differently typed parameters anyways).
dbemerlin
+1  A: 

The best solution would be to use data classes instead of many parameters. It looks as if you rely too much on primitive objects (strings, ints, ...), just create classes for related data. If there is no good relation then you can also use classes with a single property, that way the compiler will complain if the ordering is incorrect and your code is extensible if you at some point need more properties (i.e. a method now doesn't just need the name of an item but also the id).

If that is no option then you can try to stick to a pattern for the ordering of parameters (something along the lines of "parameter 1 is always the source string, ...)

dbemerlin
+4  A: 

Use javadoc, it is your friend.

With any good IDE, doing mouse-over the name of the method should give you a tool tip window with useful information.
I know that with Eclipse, if your javadoc makes use of the @param tag, your chances for confusing which parameter is which will go down greatly.

JustJeff
appreciating that drive-by down vote, whoever you were. please explain to us exactly how you feel documentation is a bad thing?
JustJeff
A: 

Your best bet in Java is to create a simple parameter JavaBean - that is, a plain old Java object (POJO), with getters and setters for each one of the parameters. Then, your method signature could be:

void mymethod (Parameters parametersObject)

and the Parameters JavaBean would have setParam1(...), setParam2(...), setParam3(...), and so on, and could even do some basic internal validation, provide default values, and so on.

If you do not want to go through with creating the Parameters object, use a Map, but then you would have to do additional checking inside of your method for missing parameters. Also, the keys to the map would have to be well-known - that is, known both outside of the method, as well as inside the method.

Sualeh Fatehi
+3  A: 

Like volothamp mentioned in its answer. Named Parameters would help a lot and you can emulate something similar like them in Java as described in this question.

Most of the times especially if you are using an api that is used by third parties you want to have data objects that store parameters for constructors or methods that take more then three parameters. This is a pattern called parameter objects. This enables you to do input checking in the parameter object and keep you methods cleaner etc.

If you create a parameter object that has only setters you have a clear naming for the client to see where to put its data. Like in this example:

public printAddress(String name, String street, String city) {...}
print address(name, street, city);

If you use a parameter object you have something like that:

public printAddress(Address address) {...}

Address address = new Address();
address.setName(name);
address.setStreet(street);
address.setCity(city);

printAddress(address);

This is more code but it will be much more readable. If you want to reduce the lines of code needed you could go with method chaining. Make the setters return the object they work on. The code now would look like this:

public printAddress(Address address) {...}
printAddress(new Address().setName(name).setStreet(street).setCity(city))

This looks strange on the first sight but if you are used to it it will make the code smaller more readable and you want have to deal with all the debugging questions from your client.

Janusz