Skip to main content

Properties are Design Features

Posted by cayhorstmann on January 18, 2007 at 11:42 AM PST

Mapping Design Intent to Code

??? style="float: left; margin-right: 1em; width: 10%;" />Chapter 3 in
Fowler's UML
Distilled
discusses class diagrams. His first design
concept: properties
. Fowler describes the role of properties in
OO design and how they are mapped to language features in Java and C#.

In Java, a public read-write property can be
mapped to a getter and setter pair. The design concept

/** the name of this widget */
public property String name;

gets mapped into

/**
   Gets the name of this widget.
   @return the name of this widget
*/
public String getName()
{
   return . . .;
}

/**
   Sets the name of this widget.
   @param name the new name of this widget
*/
public void setName(String name)
{
   . . .;
}

What's wrong with it?

  • Not very DRY
  • Humans and tools need to rediscover the designer's intent

Making the mapping from design to code clear and traceable should be
the job of the programming language.

After all, why do we program in Java? You can implement classes in
C—just use struct, write the virtual method tables with
macros, and use some discipline.

Or, to use a more recent analogy, consider the enhanced for
loop. Why do we prefer

for (String w : words)

to

for (int i = 0; i < words.size(); i++)
{
   String w = words.get(i);
   . . .
}

You could argue that the enhanced for loop is a deplorable
sign of language bloat and that it is properly the job of the IDE to write
the explicit loop.

Or you could argue—as the designers of this feature
have—that the enhanced for loop reduces the cognitive load
on the code reader because it is a more faithful translation of the
programmer's intent, namely to loop through all elements.

I think the IDE argument is completely bogus. I don't care about the
keystrokes. I know perfectly well how to get my IDE to type stuff. I care
about reading the code later. When I read the explicit loop, I look
at the indexes, the < sign, the ++. When they are all
just so, I say to myself “aha—I rediscovered the intent; we
really want to loop through all elements”.

As you can tell, I buy into the “intent” argument. Going
back to properties, when I design a class, I think of properties, not
getters and setters. I want that intent reflected in the code. I don't
want to piece together a dozen lines of getter/setter code, checking that
all the names and parameters are just so.

Designing With Properties

The most common argument that I hear against properties is “they
are bad design—just like public fields”.

There is an essential difference. Once you expose a public field, you
can never change the implementation. But with a property, you can start
out
with a trivial implementaton and refine it later, e.g. add
error checking in the setter, or switch from field access to a computed
result.

The usual trite example: Start with a trivial implementation.

/** the name of this widget */
public property String name; // compiler auto-generates trivial getter/setter

Later, refine it to

/** the name of this widget */
public property String name
   get { return fname + " " + lname; }
   set { String[] n = value.split(" "); fname = n[0]; lname = n[1]; }

(Yes, I know the setter needs better error checking. That will be the
next refinement)

(Yes, I know that the number of keystrokes isn't all that different
from using a regular old getter/setter. That's unimportant. What s
significant is that the programmer intent is captured by grouping the
implementation features together.)

??? src="http://www.agilemodeling.com/images/models/classDiagramSketch.JPG"
style="float: left; margin-right: 1em; width: 25%;" title="" />Another
commonly voiced argument is: “You should not expose all internal
state through getters and setters”.

To which I say: “Amen”.

When designing a property, I ask myself whether this is indeed an
intrinsic feature of the class that will always be there. Does it make
sense to allow public read access? Public write access? The fewer
properties, the better.

Some people argue that we shouldn't add property support to Java
because clueless programmers would abuse it. But they already abuse it
today, aided by the getter/setter auto-generation in the IDE. Is Eclipse a
tool of the devil because it makes writing bad code so easy?

Design is hard. The class designer has the arduous task of producing a
public interface that is rich enough to make the class usable and frugal
enough to make it withstand change. I don't know how to simplify that
task. All I ask for is that—once a capable design has been
completed—the design intent is right there in the Java code, rather
than making me recover it from a rubble of code.

Related Topics >>