Sponsored Link •
This article gives you a simple trick you can use to make your Java method calls more readable when the list of parameters contains booleans and numeric primitives.
Now that I've gotten myself onto the Groovy mailing list, I'm getting involved in language discussions again. I love those. The axe I generally grind in those discussions is readability. To me, that is an overlooked strength of the Java language that goes a long way towards explaining its popularity as a vehicle for production applications and for teaching. A recent discussion reminded me of a trick I use to make method calls more readable in Java--which can become something of a problem when the list of parameters contains booleans and numeric primitives. In this article, I share that trick with you.
You're looking through code written by someone else, or that you wrote long ago (in a galaxy far away), and you find a method call like this:
addValue(13, 47, true);
The question is, what do the parameters mean?
Of course, you can search for the addValue method, navigate to it, and read it to find out what the values mean, but that means you're no longer reading the code, so much as translating it. It's as though you're reading a book written in a foreign language, with the book in one hand and a translation dictionary in the other. If you only have to do it once in a while, it's not too bad. But if you're doing it all the time, it becomes a problem.
In general, code that has to be "translated" is a major headache for the hapless victim who has been tasked with modifying it--a victim who more often than not turns out to be myself, 6 months later when I have completely forgotten all of the things I had in my head when I wrote the original version. So in an effort to make things slightly simpler for my future self, I began looking for ways to make such method calls more readable.
A simple solution is to add variables that make the meaning clear:
int value = 13; int location = 47; boolean overwrite = true; addValue(value, location, overwrite);
That code is self-documenting, so it's quite a bit more readable. It does add some length, though. And the next time you invoke addValue in the same scope, the code has to change slightly to remove the variable declarations:
value = 13; location = 47; overwrite = true; addValue(value, location, overwrite);
It's a small thing, I know, but the code just became a little less consistent. And it's 3 lines longer every time you make that call.
To shorten the code, you might be tempted to reuse a variable like overwrite, for example. The code then reduces to
value = 13; location = 47; addValue(value, location, overwrite);
That's shorter, but the reader has just gone back into the translation business. To make sense of the code, they have to answer the following questions:
Is overwrite a boolean or an integer?
(To answer that, they have to find the definition.)
The simple solution does improve readability to a degree, if you avoid the trap of reuse. But it turns out that there is an even better way to make your method calls readable.
The solution that provides maximum readability is to declare variables without defining them, and do the assignments only when using them in a method call. The code template looks like this:
int value; int location; boolean overwrite; ... doIt(value=13, location=47, overwrite=true);
Although I usually don't declare multiple variables on a single line, I do so here to indicate that they are never intended to take a default value.
Some sort of naming scheme might also make sense for that purpose. For example, a Hungarian prefix like "z" could be used to indicate a parameter-variable. It would sound like French-English for "the", and would produce variable names like zValue, zLocation, and zOverwrite. Any reference to such a variable that did not also provide a value would be considered a stylistic error. (In the ideal word, either the compiler or a lint-sytle utility would give you a warning.)
With this mechanism, the method call doIt(value=13, location=47, overwrite=true) now accomplishs three goals, all at the same time, in the least possible space:
Finally, note that the ordering of these "named parameters" is always preserved. The names exist for semantic clarification--they do not permit you to change the order of the parameters--a facility which tends to produce readability problems of its own.
Using "named parameters" for boolean and numeric primitives is way
to go for readable method calls.
|Eric Armstrong has been programming and writing professionally since before there were personal computers. His production experience includes artificial intelligence (AI) programs, system libraries, real-time programs, and business applications in a variety of languages. He works as a writer and software consultant in the San Francisco Bay Area. He wrote The JBuilder2 Bible and authored the Java/XML programming tutorial available at http://java.sun.com. Eric is also involved in efforts to design knowledge-based collaboration systems.