Monday, October 02, 2006

Are public fields truly evil?

I guess it might be considered heresy to ask this question, but:

Are public fields in a class truly evil?

To start off, I have been programming java since 1998, and know all about the idea of hiding the implemention so that you can change it without affecting the calling code (and all that stuff). I understand how thats a Good Thing when you are developing components to be used by other teams. In that case you would almost always want to hide access to your class(es) fields behind getters/setters. I wonder if that same rule really applies to smaller web teams, though.

For instance, until early September, I was the only java developer on forgetaway.com..now there are 2 of us. And, i doubt we get much bigger. So, for this website, there are at present 2 guys who work with the java code, and of course this code will not be made generally available to the public. In cases like this, what are the real benefits of making fields private and hiding access behind getters and setters? All it really does is clutter up the code.

All i can really go on is my experience in web programming for the last 7 years, but i can't see how making fields private has really saved our team from abusing our API. In my experience with weather.com and now forgetaway.com, field types usually (like 95% of the time) dont change. If i create a field as a String, its pretty much gonna stay a String, same for Ints, Dates, and the occasional Float (not to mention that we really never changes column types in the db, so the field types in the model objects just dont change). Having to access fields with getters really doesnt do anything but add keystrokes (yeah, i use eclipse and code completion does most of the work). And, since our team is pretty small...who is gonna abuse the API if fields are public? Plus, in the 5% of the time the fields might change or need their data massaged, with modern IDEs its pretty easy to refactor and modify the necessary references.

Note that this argument only applies to fields where the getter/setter methods do not modify the field in any way. For example, if you have a getter that modifies the returned result if the field is null, then of course the getter makes sense. But if the getters and setters for a field are simple dumb returns of the field value, I dont see that its providing that much value in a standard small web development shop. In fact, accessing public fields directly for the dumb setters/getters, and having to use a getter when the field value is modified, makes it more obvious when you are calling a method that possibily modifies the field before return (since you would only create a getter/setter for field values that needed some sort of massaging. Usually, i like to make a separate method, like getFieldFormatted() or something, if i modify the contents of a field. That way my model data itself stays pure.)

So, in short, if your development involves these scenarios/rules below, whats the harm in making fields public and just forgetting about the getter/setter bloat?
  • You are working on a internal project and your code will never be used by the public at large (i.e. you arent developing an API to be used outside your team)
  • You are working on a small development team
  • The field does not massage the data retrieved from the db. How its retrieved from the db is how it will be showed on the page.
  • You already create additional getters/setters for a field if you need to modify the field in some way.
Finally, i know that getters/setters arent usually adding thousands of lines of code to your programs, but i do think its a symptom of the following: I guess this is a controversial idea, but i think (especially in the java world) things have gotten to a point where stuff is so overdesigned or overengineered that we add layers and complexity that we dont really need. Yeah, in a perfect, pure OO world, the setters/getters are the way to go. But in a real world, internal small team development project...do you really ALWAYS need such purity? Arent there some things we can get rid of to speed development, and make our code a little more compact?

2 Comments:

At 10:03 AM, Blogger Ricky Clarkson said...

Try, where you can, to code to interfaces, and use anonymous classes for implementations.

If you do that, you'll probably find that you need less setters.

The less setters in your code, the less problems you will have with sharing objects (i.e., their state).

Obviously, if you rely on beans everywhere then this might not be applicable.

Take a look at functional programming sometime. Two main ideas:

1. You don't change things, you make new versions of them (think of adding a String to a String in Java). This property means that pure functional programs are inherently thread-safe.

2. You can compose functions, so that you only need to express an algorithm once, and pass in the bits that change.

Access modifiers in Java are pretty meaningless if you use encapsulation, such as anonymous classes.

A nice side-effect is that IDEs can tell you if you define something that is unused in an anonymous class, even if it is a public member.

I don't think they can do that (yet) for named classes, except via code coverage measurement, or individual usage searches.

 
At 5:25 PM, Anonymous sal said...

Why not use a Map?

I find that beans are used for many instances where a Map would work just fine. I used them for spring-mvc input forms all the time, and they work great when combined with JDBCTemplate queryForMap().

 

Post a Comment

Links to this post:

Create a Link

<< Home