Named parameters in Java (updated)
Creating a method that has many parameters is a major sin. Whenever there is a need to create such a method, sniff in the air: it is a code smell. Harden your unit tests and then refactor. No excuse, no buts. Refactor! Use builder pattern or even better use Fluent API. For the latter the annotation processor fluflu may be of great help. (Update: as of 2019. fluflu is deprecated. Use a more modern and handier solution: Java::Geci.)
Having all that said we may come to a point in our life when we face real life and not the idealistic pattern that we can follow in our hobby projects. There comes the legacy enterprise library monster that has the method of thousands of parameters and you do not have the authority, time, courage or interest (bad for you) to modify … ops… refactor it. You could create a builder as a facade that hides the ugly API behind it if you had the time. Creating a builder is still code that you have to unit test even before you write (you know: TDD) and you just may not have the time. The code that calls the monstrous method is also there already, you just maintain it.
You can still do some little trick. It may not be perfect, but still something.
Assume that there is a method
public void monster(String contactName, String contactId, String street, String district,
...
Long pT){
...
}
The first thing is to select your local variables at the location of the caller wisely. Pity the names are already chosen and you may not want to change it. There can be some reason for that, for example, there is an application-wide naming convention followed that may make sense even if not your style. So the call
monster(nm, "05300" + dI, getStrt(), d, ... , z+g % 3L );
is not exactly what I was talking about. That is what you have and you can live with it, or just insert new variables into the code:
String contactName = nm;
String contactId = "05300" + dI;
String street = getStrt();
Street district = d;
...
Long pT = z+g % 3L;
monster(contactName, contactId, street, district, ... ,pT );
or you can even write it in a way that is not usual in Java, though perfectly legal:
String contactName, contactId, street, district;
...
Long pT;
monster(contactName = nm, contactId = "05300" + dI, street = getStrt(), district = d, ... ,pT = z+g % 3L );
Tasty is it? Depends. I would not argue on taste. If you do not like that, there is an alternative way. You can define auxiliary and very simple static methods:
static <T> T contactName(T t){ return T;}
static <T> T contactId(T t){ return T;}
static <T> T street(T t){ return T;}
static <T> T district(T t){ return T;}
...
static <T> T pT(T t){ return T;}
monster(contactName(nm), contactId("05300" + dI), street(getStrt()(, district(d), ... ,pT(z+g % 3L) );
The code is still ugly but a bit more readable at the place of the caller. You can even collect static methods into a utility class, or to an interface in case of Java 8 named like with
, using
, to
and so on. You can statically import them to your code and have some method call as nice as
doSomething(using(someParameter), with(someOtherParameter), to(resultStore));
When all that is there, you can feel honky dory if you answer the final question: what the blessed whatever[sup]* is parameter pT
.
(* "whatever" you can replace with some other words, whichever you like)
Comments imported from Wordpress
Mircea 2014-09-01 07:52:23
Cool. I didn’t know that neither. :) Thanks.
Laszlo Gazsi 2014-08-27 11:25:56
Wow, I didn’t know it was possible to pass the parameters as: monster(contactName = nm, contactId = "05300" + dI, street = getStrt()… This will come very handy in the project I currently work on, since it contains dozens of methods with too much parameters. And it becomes even more frustrating when you see a method call like someMethod(someArg, null, null, null, someArg2, null, "", null, null).
Thank you for sharing!
Adam 2014-10-22 12:14:47
It’s just assignments to those dummy variables in the same line, not some special parameter passing, of course. But good idea nevertheless.
Generating Source Code, a Compromise | Java Deep 2018-05-23 15:01:08
[…] with edit time source code generation. I created tools like Fluflu mentioned in my article “Named parameters in Java“, or Scriapt Java annotation processing tool described in the article “Don’t write […]
Comments
Please leave your comments using Disqus, or just press one of the happy faces. If for any reason you do not want to leave a comment here, you can still create a Github ticket.