Test Driven Development: Programming by Intention

Have you ever had to work on a piece of code and found that it was hard to understand? Maybe the logic was convoluted, the identifiers meaningless, or worse, misleading. You say there was documentation? Was it readable? Did it make sense? Was it up to date with the code? Are you sure? How do you know? This chapter discusses programming by intention, a central idea in XP. It means making your intent clear when you write code.

This chapter discusses programming by intention, a central idea in XP. It means making your intent clear when you write code.

Have you ever had to work on a piece of code and found that it was hard to understand? Maybe the logic was convoluted, the
identifiers meaningless, or worse, misleading. You say there was documentation? Was it readable? Did it make sense? Was it
up to date with the code? Are you sure? How do you know?

The main idea of programming by intention is communication, specifically, the communication of our intent to whomever may be reading the code. The goal is to enable them to understand what we had in mind when we wrote the code.

Let's look at what we need to do in order to have our code be as understandable and intent-revealing as possible.

NAMES

By names I mean the identifiers we choose to name the various classes, variables, methods, etc., that we create as we work. We need
to choose names that are semantically transparent, that is, they say what they mean and mean what they say.

When I'm talking about choosing names, I like to pull out the quote from Romeo and Juliet that appears at the beginning of this chapter. We can use whatever word/name we like to refer to a thing, but if it does
not convey the meaning that we intend then it is an enemy of clarity and may serve to confuse people who read or work on this
code in the future. The lesson here is to use names that make sense. . . call it what it is.

My oldest daughter used to have a cute, although somewhat annoying, habit of coming up with her own names for songs and stories
that she liked. She would focus on one line from the whole song/story and derive a name from that. Many nights at bedtime she would ask frantically
for a new favorite, while we went through a game of Twenty Questions to try and deduce what she was talking about. This is a danger of using non-obvious names for things. Sure, it may make sense
to us, but what about everyone else?

There are several patterns that we can use when choosing names; we discuss them in detail next.

Use nouns or noun phrases for class names.
Name classes for what they represent or what they do:

Use either adjectives or generic nouns and noun phrases for interfaces.
Interfaces are a bit different. If an adjective is used for an interface name it usually ends with -able, for example, Runnable, Serializable. My advice is to avoid conventions that prepend or append "I" to the name when possible. Sometimes there isn't a good name
for an interface other than "interface to something." In that case, ISomething is acceptable.

Use accepted conventions for accessors and mutators.
Many languages have generally accepted conventions for how to retrieve and modify instance variables. For instance, if you
are working in Java, you are advised to use the Java Beans conventions of getX and setX to retrieve/modify a variable named x.

To access a boolean variable, use isX in both Java and Smalltalk. An alternative in some cases is to use the form isX() where X refers to an optional part of the object; for example, either of the following could be used:

Note that this applies to computed properties as well as actual instance variables, for example, when a circular queue class
needs a method to query whether it is full, we suggest isFull.

Sometimes it is clearer to drop the get prefix. For example, I tend to use size rather than getSize to fetch the size of a composite object. This is often the case when the value you are asking for is a property of the object
as opposed to one of its attributes.

public int size() {
return movies.size();
}

In this case, we are also conforming to the convention used in the Java class libraries. It is a good idea to conform to the
naming idioms of the environment you are working in because that is what others who will be reading your code will be accustomed
to.

Don't put redundant information in method names.
If I needed a method to add an instance of X, I would tend to call the method add rather than addX since the parameter will be an X. This has the benefit that if later refactoring changes the type of the argument (even simple renaming of the class), then
the method name is out of sync with its argument. The innocent redundancy has now become misleading and confusing. Another
benefit is that you gain clarity if you need to support adding of different types by the ability to overload the method name.

Choose names carefully, but don't spend too much time at it. Remember, they are easy to change. If later we decide that a
different name would communicate the intent better, it can be changed. That's one of the most basic refactorings. Using a
tool that has automated refactoring support helps.