Core Java

Named parameters in Java

Creating a method that has many parameters is a major sin. Whenever there is need to create such a method, sniff in the air: it is 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.

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 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* is parameter pT.

(* “whatever” you can replace with some other words, whichever you like)

Reference: Named parameters in Java from our JCG partner Peter Verhas at the Java Deep blog.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

5 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Matthias@Java
Matthias@Java
9 years ago

This is a typical example for miswritten source. There is a possiblity to extract the adress to an own class, because the monster has got not the tast to administrate the adress. A method shall only have a short parameter lsit. So using the method shall be easy to understand. In that case the author writes “The code is still ugly”. This is a sign that the author does know that the source is bad and he had no idea to refactor the code to be readable to other peoples.

Peter Verhas
Peter Verhas
9 years ago
Reply to  Matthias@Java

Thanks for the valuable comment. Now I clearly see about what I had or had no idea about.

Chip McCormick
Chip McCormick
9 years ago

Assuming monster(…) isn’t a constructor, my first approach would be to make the call more object oriented. Create an Address and Contact object, probably with validate() methods, and make those the parameters. I’m not convinced that the static approach is much of a gain over the Builder pattern. Either the builder methods are like the static methods and lack business logic and validation, in which case TDD and unit tests don’t help much, or there is logic, in which case either approach probably should be tested. It’s easier to unit test a Builder than static methods and as a “pattern”… Read more »

Peter Verhas
Peter Verhas
9 years ago

Please note, that the article, as described in the first paragraph, is about a situation when you have no time, resource and/or authority to the right thing. I gave an example showing that something still can be done.

Yannick Majoros
Yannick Majoros
9 years ago

> Please note, that the article, as described in the first paragraph, is about a situation when you have no time, resource and/or authority to the right thing.

With any modern IDE, it’s faster to do it right, e.g. make an Address class as suggested in first comment.

Back to top button