3.4. Code Communicates

 <  Day Day Up  >  

A primary purpose of code is communication. You are communicating with the computer, telling it what operations to perform. However, you are also communicating with the reader, showing him the steps you are taking to complete an operation. The most important issues to communicate are what are you doing and why you are doing it, not how you are doing it.

Code should communicate its purpose and your intention . On at least one level, code should read like a book, albeit one with stilted syntax. The client should be able to read the code to see if it follows the logic that he expressed in the requirements. The details of the implementation should be relegated to deeper levels.

When reading code, it is often difficult to determine intent. If the writer did not take particular care to make his intent clear, it might be buried in the details. The "micromanagement" of details can hide the flow of the logic.

For example:

 if (a_customer.has_late_rental (  ))         a_customer.suspend_rental_privilege(  ); 

This code does not show how the suspension of rental privileges is recorded. It states why the person is being suspended (because of a late rental). The client should be able to follow the logic involved, without getting buried in implementation details.

COMMUNICATE WITH YOUR CODE [*]

Your code should communicate its purpose and intent.


[*] See Literate Programming by Donald Knuth (Center for the Study of Language and Information ”Lecture Notes 1992) and The Elements of Programming Style by Brian W. Kernighan and P. J. Plauger (Computing McGraw-Hill, 1978) for original discussion on communicating with code.

Code readability is measured by whether someone else can read it. The pair programming practice of Extreme Programming ensures that two people can read the code. If you are solo-programming, Nitin Narayan, a reviewer, suggests, "Readability of code is best verified when tested by two or three programmers who read the code and explain what it does to the actual coder. I call this the code readability test. The coder can then change his code to make it more readable based on the feedback he gets from the code readability testers."

3.4.1. Implicitness Versus Explicitness

Implicitness makes programs shorter, but can make them less readable by programmers who are less experienced in the language or who use many languages simultaneously . Implicitness requires that you make assumptions about the programmer's knowledge. Explicitness requires more writing, but uncertainty as to interpretation is minimized.

For example, in object-oriented languages that feature namespaces, you can refer to classes by using a fully qualified name (e.g., java.util.Vector ), or by using an import statement (e.g., import java.util.* ) and an unqualified name ( Vector ). Some coding standards suggest that you always use a fully qualified name. With the fully qualified name, it is clear to the reader to which package a class belongs, without having to have detailed knowledge of the packages.

You cannot be explicit about everything. You need to assume a common body of knowledge, such as the way the Java language is written. However, domain- related code requires more explicitness . You cannot assume that another programmer will know (or remember) every detailed piece of information you learned from the customer.

EXPLICITNESS BEATS IMPLICITNESS

Being explicit reduces misinterpretation.


A FEW MORE WORDS GIVE MEANING

Microsoft's MFC library has a method called UpdateData( ) . The purpose of the method is twofold. It retrieves the values in display controls on the screen and places them into class members , and it sets the values in the controls from the member variables . Which operation it performs depends on whether the parameter is TRUE or FALSE . Now you tell me, if it is TRUE , should it retrieve the values from the text boxes, or set them? UpdateData( ) is an example of a method that could use a better name. It would be more understandable if it were broken into two methods , such as RetrieveValuesFromWindowControls( ) and SetValuesOfWindowControls( ) . These names might be a little wordy, but they really express the meaning.


Jason Hunter provided an example from JDOM:

The Element.getText( ) method returns the text of the element . According to XML rules, it should return all whitespace. People often do not care about surrounding whitespace, so a method was needed that trimmed the whitespace. Some people proposed getText(TRue) where TRue indicates to trim the whitespace. However, the Boolean parameter did not have an obvious purpose.

What Hunter finally chose to implement was getText( ) and getTextTRim( ) :

The XML purists were happy because getText( ) followed the spec, and most people could add four characters and get what they really wanted. Furthermore, the method name explains what it does.

Later he added a getTextNormalize( ) method that normalizes internal whitespace. That would have been hard using a Boolean switch.

3.4.2. Spell It Out

You might notice an emphasis on names in this book. Getting names to say what you mean and to be consistent makes code more understandable and readable. However, names appear in many places other than code: database column names, XML tags, and user documentation. Create meaningful names in the beginning and use these names in all these other contexts. Then the complete system will be more understandable and maintainable .

It might seem obvious, but you should avoid using names that differ only in a single character or that appear practically the same on the screen. Virus writers do that to fool unsuspecting users. A virus might be named rundlI.dll , which is hard to distinguish from rundll .dll in the normal font on most systems. Following along the lines of error-detecting codes, there should be a noticeable distance between two names. At least two characters should be changed to convert one name into another. If you like to use single-character variables for loop indexes, pick letters that are distinctly different ”e.g. i and k , rather than i and j .

READABILITY OR RDBLTY?

A few years ago, I developed some FORTRAN routines that manipulated orbital elements. Orbital elements describe the orientation and shape of a satellite's orbit . They are calculated from a satellite's position and velocity. The version of FORTRAN I was using allowed only six-character names. I created a routine that computed orbital elements and named it CMPORB. I created another routine that compared two sets of orbital elements and named it ORBCMP. Even though I created the routines, I could never keep straight in my head which one performed what operation. The parameter list gave a bit of a clue, but then the parameters themselves had only six-character names. Use readable names.


Modern languages have removed limits on variable names. The names themselves can communicate their meaning. Smart editors provide for autocompletion of names, so repeatedly typing a long name is not required.

You should use abbreviations and acronyms only if the client or the problem domain uses them. Names can be shorter if they are referred to only locally (inside a method). For example:

 for (int m = 0; m < SIZE; m++)         {         // Use m inside of here         } 

However, any name that is exposed outside the method (such as parameter names) should be spelled out fully for readability.

3.4.3. Spellcheck Your Code

Many programs these days offer spellcheckers. Spellchecking ensures that your words are at least spelled correctly, even though they might not be used correctly. Compilers offer syntax checkers. They ensure that the words are used correctly, but they do not ensure that they mean anything.

You can run a spellchecker on your code to see whether the code terms have meanings in a particular language. You can parse camelcase words ( SomethingLikeThis ) or underlined words ( something_like_this ) into separate words prior to spellchecking. Before the spellcheck , you can add to the list of correctly spelled terms the acronyms and abbreviations that the developers and clients have agreed upon. [*]

[*] Go to http://www.oreilly.com/catalog/prefactoring for a simple spellchecker that runs on Unix/Linux.

3.4.4. Adapt Your Style to the Environment

Some relevant communication factors are people and time. If you are writing a program that only you are using, communication is much less of an issue. If you are writing a program that someone else will use or maintain, communication is a concern.

I use pseudocode to explain algorithms in this book. You can write pseudocode to look more like normal English, or you can stylize it to resemble actual code. I usually write pseudocode to determine how to approach a problem. If I am creating a quick little program to solve an immediate problem or to try out an idea, I might turn the pseudocode into comments and then code the implementation between the comments.

However, if I am writing a larger program, the pseudocode is transformed into the actual code. The names used in the pseudocode become the operations in the classes, with alterations for consistency or grammar. The operations spelled out in the pseudocode are implemented in methods and the implementation is placed within the methods. The pseudocode operations express the what . The methods describe the how .

 <  Day Day Up  >  


Prefactoring
Prefactoring: Extreme Abstraction, Extreme Separation, Extreme Readability
ISBN: 0596008740
EAN: 2147483647
Year: 2005
Pages: 175
Authors: Ken Pugh

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net