-
Get a monthly update on best practices for delivering successful software.
I've gotten lots of feedback, much of it asking "what's the alternative?" to using beans and getters and setters. I'll make a deal with my skeptical readers. I'll argue the negative, with examples, if they argue the affirmative. In other words, you show me some places where you can't get around using getters and setters and I'll show you all sorts of places for the next few weeks, from real open source projects, where people have screwed the pooch with unnecessary getters and setters.
For my first trick, I give you JChemPaint.java from the JChemPaint project:
if (file.getName().toLowerCase().endsWith(".cml")) { FileUtils.saveModeltoCMLfile(file, getCurrentModel()); } else { FileUtils.saveModeltoMDLMolfile(file, getCurrentModel()); }
This little beauty sits inside a Swing Action's actionPerformed() method. Sweet. There's similar logic for loading and renaming files as well. The point is that this logic shouldn't be sitting in the UI layer at all. It should probably reside in FileUtils. If you want to go a touch farther, you could have a working document model that contains the file name, whether the model has been modified without being saved (a "dirty" flag), etc. This would wrap the base model and intercept calls that might necessitate updating the dirty flag.
There are other ways to go here, but I think you can see how the tempting getName() led to introduction of file name extension logic here.
OK, tag, you're it. I look forward to seeing cases where getters and setters are absolutely necessary.
Related posts:
Topics: Antipatterns, Beans, Design Patterns, Java, OOP
Ok, you are displaying a grid of orders. The orders have properties such as quantity ordered, date ordered, etc. How are you displaying those properties in the grid?
Comment by Paul B., Monday, March 2, 2009 @ 7:57 pm
“There are other ways to go here, but I think you can see how the tempting getName() led to introduction of file name extension logic here.”
What?! No, I can’t see that at all. Are you saying I should not be able to retrieve the textual name of a File? What if I (*gasp*) wanted to print the name of the file to a JTextArea or JLabel? What if I wanted to log the name of the file currently being operated on to a log file? It’s just insanity to remove the ability to convert a File object into its textual representation. Everywhere I ever needed to work with both a textual representation of the filename and also the File object, I would have to pass two arguments instead of one. Not to mention the hassle of return values, where you are limited to returning a single argument, so passing both the textual representation and the File object itself is not even an option unless you return an array or some sort of wrapper class, which defeats the purpose of separating them in the first place.
The cause of this poorly designed code is poor design, not Getters and Setters. Trying to solve design flaws with syntax-level solutions is like trying to turn a 2 year old into a master painter by giving him more expensive paint.
Comment by what, Tuesday, March 3, 2009 @ 7:17 pm
The example given is not a good argument about the use of getters and setters.
Objects should have both state and behavior.
Getters and setters are evil when used to process data related to that class. For example having a Sale class do this:
salesLineItem.setTotal(salesLineItem.getQty() + salesLineItem.getPrice())
rather than this
salesLineItem.calculateTotal()
is an abuse of getters/setters.
Following the ‘expert’ pattern, an operation that requires knowledge of state should reside in the object that contains the state.
Comment by Mark, Wednesday, March 4, 2009 @ 7:46 pm
[...] time we came this way we looked at the misuse of a getter in the java.io.File. Not that it was wrong to have a getter in File, just that is lead to misuse of that information in [...]
Pingback by Agile Ajax » Bean of the Devil: Tally-Ho CMS » Pathfinder Development, Saturday, March 21, 2009 @ 4:17 pm