الأحد، 1 أغسطس 2010

Why we are actually writing getters and setters in Java

I now often hear the opinion that writing getters and setters has something to do with better encapsulation, that using “naked” fields is bad practice. To find out if this is true, we have to look at Java history. In the mid-nineties, Sun developed the Java Bean Specification as a component model for Java. This model was supposed to help with tool support for Java, e.g. when connecting a graphical user interface with domain objects. In this case, it is useful if one can observe changes made to fields and react to them (e.g. by updating the text displayed in a window). Alas, while there are some languages that allow this kind of meta-control (Python and Common Lisp come to mind), Java does not. Thus, Java Beans introduced standardized naming that allowed one to implement a field as a pair of methods which then would manually implement the observation.



I usually code as follows: If I need just a field, I use a public field (no getters and setters), because it helps me to get started quickly and introduces less clutter. If I later change my mind, I let Eclipse introduce the indirection of the getter and setter. That means that there is no penalty for such a change and no need to think ahead! Granted, having both public fields and getters/setters affects uniformity, but the added agility is worth it for me.



Obviously, it would be nice if Java had true observable (and optionally computable) fields. This feature was initially on the table for Java 7, but did not make the cut. Maybe IDEs could help by displaying getters and setters as if they were fields. Their source code would be hidden, with visual clues indicating if such a pseudo-field is read-only etc. Additionally, auto-expansion would be improved, because pseudo-getters (such as Collection.size()), getters/setters, and fields would all be part of the same category. No more typing “.get” and hoping that the information that you are looking for is available as a properly named getter. The same kind of grouping should also be made in JavaDoc. Lastly, one could display foo.setValue("abc") as foo.value = "abc". But I’m not sure if that makes sense.



Addendum (2010-08-07): I think I did not make my point clear. It was not “use public fields”, it was “don’t use getters and setters blindly”. I’m applying the coding style mentioned above during an exploratory phase of coding. IDEs such as Eclipse allow you to do this kind of quick and dirty exploration because real getters and setters are always just a refactoring away. I do agree that, as soon as the API and its client code are not in the same code base, you cannot do these refactorings, any more. Thus, you have to think ahead and freeze some things.



As for generating getters and setters: Yes, Eclipse does that for you. It even expands getFoo into foo getter source code and setFoo into foo setter source code. And it can also rename the setters and getters for you while renaming a field. Even then, getters and setters still add clutter.

ليست هناك تعليقات:

إرسال تعليق