< 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.
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 ExplicitnessImplicitness 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.
Jason Hunter provided an example from JDOM:
What Hunter finally chose to implement was getText( ) and getTextTRim( ) :
Later he added a getTextNormalize( ) method that normalizes internal whitespace. That would have been hard using a Boolean switch. 3.4.2. Spell It OutYou 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 .
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 CodeMany 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. [*]
3.4.4. Adapt Your Style to the EnvironmentSome 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 > |