Method parameters confusion
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 开发者_如何学Gothis sort of mistake (apart from unit tests) ?
You are searching for: Named Parameter idiom in java
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.
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.
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, ...)
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.
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.
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.
精彩评论