Java.next -- Four languages that represent the future of Java
Blogger Stuart Halloway has begun a series of posts on trends that point to the future of the Java platform. In his first post, he compares Clojure, Groovy, JRuby, and Scala -- four wildly different languages that nonetheless all play together in the JRE. Find out what unites these languages and what they can tell us about the future of Java-based development ...

Newsletter sign-up

Sign up for our technology specific newsletters.

Enterprise Java
View all newsletters

Email Address:

Why getter and setter methods are evil

Make your code more maintainable by avoiding accessors

Page 3 of 5

Since accessors violate the encapsulation principle, you can reasonably argue that a system that heavily or inappropriately uses accessors simply isn't object oriented. If you go through a design process, as opposed to just coding, you'll find hardly any accessors in your program. The process is important. I have more to say on this issue at the end of the article.

The lack of getter/setter methods doesn't mean that some data doesn't flow through the system. Nonetheless, it's best to minimize data movement as much as possible. My experience is that maintainability is inversely proportionate to the amount of data that moves between objects. Though you might not see how yet, you can actually eliminate most of this data movement.

By designing carefully and focusing on what you must do rather than how you'll do it, you eliminate the vast majority of getter/setter methods in your program. Don't ask for the information you need to do the work; ask the object that has the information to do the work for you. Most accessors find their way into code because the designers weren't thinking about the dynamic model: the runtime objects and the messages they send to one another to do the work. They start (incorrectly) by designing a class hierarchy and then try to shoehorn those classes into the dynamic model. This approach never works. To build a static model, you need to discover the relationships between the classes, and these relationships exactly correspond to the message flow. An association exists between two classes only when objects of one class send messages to objects of the other. The static model's main purpose is to capture this association information as you model dynamically.

Without a clearly defined dynamic model, you're only guessing how you will use a class's objects. Consequently, accessor methods often wind up in the model because you must provide as much access as possible since you can't predict whether or not you'll need it. This sort of design-by-guessing strategy is inefficient at best. You waste time writing useless methods (or adding unnecessary capabilities to the classes).

Accessors also end up in designs by force of habit. When procedural programmers adopt Java, they tend to start by building familiar code. Procedural languages don't have classes, but they do have the C struct (think: class without methods). It seems natural, then, to mimic a struct by building class definitions with virtually no methods and nothing but public fields. These procedural programmers read somewhere that fields should be private, however, so they make the fields private and supply public accessor methods. But they have only complicated the public access. They certainly haven't made the system object oriented.

Draw thyself

One ramification of full field encapsulation is in user interface (UI) construction. If you can't use accessors, you can't have a UI builder class call a getAttribute() method. Instead, classes have elements like drawYourself(...) methods.

A getIdentity() method can also work, of course, provided it returns an object that implements the Identity interface. This interface must include a drawYourself() (or give-me-a-JComponent-that-represents-your-identity) method. Though getIdentity starts with "get," it's not an accessor because it doesn't just return a field. It returns a complex object that has reasonable behavior. Even when I have an Identity object, I still have no idea how an identity is represented internally.

Of course, a drawYourself() strategy means that I (gasp!) put UI code into the business logic. Consider what happens when the UI's requirements change. Let's say I want to represent the attribute in a completely different way. Today an "identity" is a name; tomorrow it's a name and ID number; the day after that it's a name, ID number, and picture. I limit the scope of these changes to one place in the code. If I have a give-me-a-JComponent-that-represents-your-identity class, then I've isolated the way identities are represented from the rest of the system.

Bear in mind that I haven't actually put any UI code into the business logic. I've written the UI layer in terms of AWT (Abstract Window Toolkit) or Swing, which are both abstraction layers. The actual UI code is in the AWT/Swing implementation. That's the whole point of an abstraction layer—to isolate your business logic from a subsystem's mechanics. I can easily port to another graphical environment without changing the code, so the only problem is a little clutter. You can easily eliminate this clutter by moving all the UI code into an inner class (or by using the Façade design pattern).

JavaBeans

You might object by saying, "But what about JavaBeans?" What about them? You can certainly build JavaBeans without getters and setters. The BeanCustomizer, BeanInfo, and BeanDescriptor classes all exist for exactly this purpose. The JavaBean spec designers threw the getter/setter idiom into the picture because they thought it would be an easy way to quickly make a bean—something you can do while you're learning how to do it right. Unfortunately, nobody did that.

Accessors were created solely as a way to tag certain properties so a UI-builder program or equivalent could identify them. You aren't supposed to call these methods yourself. They exist for an automated tool to use. This tool uses the introspection APIs in the Class class to find the methods and extrapolate the existence of certain properties from the method names. In practice, this introspection-based idiom hasn't worked out. It's made the code vastly too complicated and procedural. Programmers who don't understand data abstraction actually call the accessors, and as a consequence, the code is less maintainable. For this reason, a metadata feature will be incorporated into Java 1.5 (due in mid 2004). So instead of:

private int property;
public int getProperty  (         ){ return property; }
public void setProperty (int value}{ property = value; }


You'll be able to use something like:

Discuss

Start a new discussion or jump into one of the threads below:

Subject Replies Last post
. procedural versus object oriented thinking
By greid
1 01/09/08 07:07 PM
by MartinHunter
. Brilliant
By daedalus_hammer
0 03/25/07 08:06 PM
by daedalus_hammer
. Ignorance
By Anonymous
2 10/05/06 10:14 AM
by Anonymous
. What a Brilliant Theory
By Albert_E
2 10/05/06 10:14 AM
by Anonymous
. Too much LDS at Berkeley?
By Anonymous
5 10/05/06 10:14 AM
by Anonymous
. thanks for the tip
By Gert
2 10/05/06 10:13 AM
by Anonymous
. Loosely Typed getters surely are not evil
By Faiser
5 10/05/06 10:13 AM
by Anonymous
. Getters and Setters in assignment work
By Anonymous
1 10/05/06 08:32 AM
by Anonymous
. A story of Joe Average ...
By Anonymous
3 10/05/06 08:31 AM
by Anonymous
. very silly article
By Patrick Calahan
1 10/05/06 08:30 AM
by Anonymous
. Things you don't get ... 2nd try ;-(
By Mariano Kamp
4 10/05/06 08:29 AM
by Anonymous
. Disagreed with this concept for a long time.
By Anonymous
14 10/05/06 08:28 AM
by Anonymous
. Have to use 'set'?
By Anonymous
2 10/05/06 07:31 AM
by Anonymous
. This is why OO has failed
By Anonymous
13 10/05/06 07:30 AM
by Anonymous
. Using Javabeans
By Anonymous
0 10/05/06 07:30 AM
by Anonymous
. How do you avoid accessors to get (essential?) info?
By Anonymous
( Pages 1 2 all )
25 10/05/06 07:28 AM
by Anonymous
. Some examples please
By Kris Thompson
15 10/05/06 07:28 AM
by Anonymous
. What about Struts and JFC paradigms?
By Anonymous
3 10/05/06 07:27 AM
by Anonymous
. What about Struts and JFC paradigms
By Anonymous
6 10/05/06 07:27 AM
by Anonymous
. Problems using this approach.
By keon
4 10/05/06 06:08 AM
by Anonymous


Resources