(borrowed from CS100 Fall 1998 by David Gries) |
|
|
|
|
|
|
|
|
|
|
|
|
Objective
A goal of CS100 is for you to learn to write programs
that are not only correct but also understandable. These guidelines should
help you toward that goal. We ask that you follow these guidelines when
writing programs in this course. They will give you a good basis for developing
a style of your own as you become a more experienced programmer.
This handout includes guidelines for Java constructs that
will be covered throughout the semester. Skim these sections now and read
them more carefully later when the topics are discussed. Not everyone agrees
on the same style: look here (under
Programming
Style) for different opinions.
Table
of contents
Outside this course, making programs readable by others becomes even more important. Most programs live a long time and require "maintenance" --changes to adapt to new and different requirements, upgrades in other software, new hardware, etc. And the author of the program is quite likely not going to be around when the maintenance is required; someone else must read the program and understand it enough to update it successfully. Even the programs you write for yourself should be readable; if not, four weeks after finishing it you will not remember it enough to make changes simply. Thus, simply for your own sake and for the sake of others, it makes sense to develop programming habits that lend themselves to writing readable, understandable, and correct, programs.
Part of these habits concern simple, syntactical measures like indenting program parts properly and using a few conventions for names of variables, methods, etc. The more important part concerns recording enough information in comments for the reader to understand how a program is designed and why. A computer program is the result many design decisions. These decisions --why this variable was introduced, what that function does, etc.-- are often not reflected in the final Java code, which consists of low-level, detailed declarations and statements. However, the higher-level design must be understood if a programmer is to modify the program successfully. Trying to understand decisions that are not recorded in comments in the code is tedious, error-prone, and aggravating --but all too common.
So, it will be to your advantage to instill in yourself some disciplined programming habits, right from the beginning, like
You will find that writing good comments as you write a program will help you clarify your ideas and write better, correct code sooner. If you can write down clearly what your program is doing you are more likely to have a good understanding of the problem and your program is more likely to be correct. Time spent on careful thinking and writing is more than repaid in time saved during testing and debugging.the comments were not of use to you when developing and debugging the program, so you took more time than was necessary. The comments are harder to write after the program is finished, because it is difficult to remember the meaning of all the variables and methods. It is quite likely that you won't write the comments --even programmers with the best intentions don't spend much time filling in comments after the fact, because there are too many other interesting things to do.
Return to table of contents
Remember that a name can rarely be used to give a complete, precise definition of the entity it names, and a complete definition should always be given where the entity is defined. The people developing Java programs have developed some conventions for identifiers, which help one readily see what the identifier represents (to some extent). You can see these conventions at work by looking at the classes in java.awt (Abstract Window Toolkit). Below, we state the conventions, with a few additions.
Package names: e.g., AnimalStory
A class name should begin with a small letter, but all successive words in the class name should be capitalized.
For example, in the two method headings given below, the first is preferable because it is shorter and easier to understand. Moreover, the body of the method of the first method will also be shorter and far easier to understand and manipulate:
// Draw an ellipse that fits
exactly within the rectangle whose
// upper left corner is at
position (x,y), whose width is w, and
// whose height is h. Use the
current color to draw the ellipse.
void drawOval(int
x,
int
y,
int
w,
int
h)
// Draw an ellipse that fits
exactly within the rectangle whose
// upper left corner is at
position (xCoordinate,yCoordinate)
// whose width is width, and
whose height is height. Use the
// current color to draw the
ellipse.
void drawOval(int
xCoordinate,int
yCoordinate,
int width, int
height)
A name like theLoopCounter or firstNumber instead of k or x causes clutter. A parameter used as a "flag" should be named for what the flag represents, like noMorePizza, rather than simply flag. Avoid generic names like count and value; instead, describe the items being counted or the value stored in the variable.
If the body of a method is short, or the places in which a local variable is used is fairly short, then a short, one-or-two letter name can be used for the local variable (see also the conventions for parameter names). A name like theLoopCounter or firstNumberinstead of kor xcauses clutter. If the local variable is used only in a short context, and if it is suitably defined with a comment at its place of declaration, then use the short name. A variable used as a "flag" should be named for what the flag represents, like noMorePizza, rather than simply flag. Avoid generic names like count and value; instead, describe the items being counted or the value stored in the variable.
There are several methods for placing curly braces that delimit statements, none of which is liked by all and all of which are disliked by some. Below, we illustrate three methods, with pros and cons explained to the right:
(0) if (x
< y) Pro: It is easy
to match up braces
{
Con: Too many lines are used, and the
x = y;
number of lines is a scarce resource on the monitor.
}
Con: The substatement {x= y; y= 0;} has
else
not been indented, because the
{
braces are part of the substatement.
x = 0;
Therefore, the basic rule concerning
y
= y/2;
indentation has not been followed.
}
(1) if (x
< y) { Pro: There are no wasted
lines.
x
= y; Pro: The opening
brace is out of the way
y = 0;
and the closing brace indicates
} else
{
nicely the end of a substatement
x = 0; Con: It is difficult
to match up beginning and end braces.
y = y/2;
}
(2) if (x
< y) Pro: There are
no wasted lines.
{x
= y; Pro: The basic indentation
rule is followed.
y = 0; Pro: It is easy
to match up beginning and
}
end braces and easy to see where a
else
substatement ends.
{x
= 0 ; Con: The first statement
of a substatement
y
= y/2;
indented differently from the rest.
}
It doesn't matter which style you use, as long as you use it consistently throughout a program. When working on a program written by someone else, match their style.
Below, we illustrate two ways to place the curly braces surrounding the body of a method. There are others. Choose one and use it consistently within a program.
(0) // Specification of methodReturn to table of contents
void drawLine(int x1, int y1, int x2, int y2) {
statement 1;
statement 2;
}(1) // Specification of method
void drawLine(int x1, int y1, int x2, int y2)
{statement 1;
statement 2;
}
// Truthify x >= y by swapping x and y if needed.The comment should explain what the group of statements does, not how it does it. Thus, it serves the same purpose as the specification of a method: it allows one to skip the reading of the statements of the logical unit and just read the comment. With suitable statement-comments in the body of a method, one can read the method at several "levels of abstraction", which helps one scan a program quickly to find a section of current interest, much like on scans section and subsection headings in an article or book. But this purpose is served only if statement-comment are precise.
if (x < y)
{int tmp = x;
x = y;
y = tmp;
}
Statement comments must be complete. The comment
// Test for valid inputis not adequate. What happens if the input is valid? What if it isn't --is an error message written or is some flag set? Without this information, one must read the statements for which this statement-comment is a specification, and the whole purpose of the statement comment is lost.
Placement of statement-comments:
In the example above, and in the
following example, the statements specified by a statement comment are
indented. In a program with several levels of statement-comments, this
indentation is useful in clarifying the structure of a program. In fact,
with several levels of statement-comments, even judicious use of blank
lines cannot eliminate all ambiguity concerning what statement belongs
to what statement-comment. The program fragment given below illustrates
this.
// Truthify the definition of t --return false if not possibleAt the highest level, the program fragment consists of two statements: (0) Truthify the definition tand (1) Store the French translation of tin tFrench. The statement "Truthify the definition of t is implemented in three steps, two of which are themselves statement-comments. Thus, this program fragment has three levels of abstraction.
// Eliminate whitespace from the beginning and end of t
while (t.length() != 0 && isWhitespace(t.charAt(0)))
t= t.substring(1);// If t is empty, print an error message and return
if (t.length() == 0)
{...
return false;
}if (containsCapitals(t))
{...
}// Store the French translation of t in tFrench
...
In this example, note how reliance on the definition of t in the statement-comment "Truthify the definition of t" allows the statement-comment to be short but precise. Of course, a suitable definition for t must appear at its declaration.)
Prefer not to indent for statement-comment?
Many people prefer not to indent
substatements of a statement-comment and to rely on blank lines to separate
the end of the substatements of a statement-comments. Below, we show the
above program fragment in this style. Note the extra comment to help the
reader see the end of the substatements for "truthify the definition of
t".
This style is has its problems. If you decide to use this style, then program
in such a way that statement-comments do not appear within statement-comments,
so that such awkwardnesses do not arise.
// Truthify the definition of t --return false if not possibleReturn to table of contents
// Eliminate whitespace from the beginning and end of t
while (t.length() != 0 && isWhitespace(t.charAt(0)))
t= t.substring(1);// If t is empty, print an error message and return
if (t.length() == 0)
{...
return false;
}if (containsCapitals(t))
{...
}// (End of Truthify the definition of t)
// Store the French translation of t in tFrench
...
// Print on System.in the most frequently occurring temperatureUnfortunately, it is more typical to find a comment like the following (if any comment is provided at all):
// in t[0..c-1]. If there is more than one possibility, print
// the least temperature.
void findCommon (Temperature [] t, int c)
// Find most frequent temperatureThis specification fails to say what part of array t is to be included in finding the most frequent temperature. It also fails to say where to print, which will be a problem if there is more than one possibility. The only way for the user to find out is to look at the body of the method (if it is available), and that should not be necessary.
void findCommon (Temperature [] t, int c)
For a function --i.e. a method that returns a value-- it is often easiest to simply describe the value returned, using the word "yield":
// yield distance between points (x1,y1) and (x2,y2)The Elements of Style, a famous little book on writing style by Cornell Professors W. Strunk, Jr., and E.B. White, contains several rules that are useful for programming as well as writing. Among them are:
double dist (int x1, int y1, int x2, int y2)
Omit needless words.Follow these rules when writing specifications of methods. For example, don't write the specification ``This function searches list x for a value y and ...'' or ``Function isIn searches list x for a value y ...''. Such specifications are too wordy and are not commands but descriptions. Instead, say the following:
Use the active voice.
// Yield "y is in list x"Return to table of contents
boolean isIn(int y, List x)
// 0 <= i <= currentItem < numberItems and i is the smallest valueThe definition for a boolean variable is usually best presented as the value of some English (or mathematical) statement. For example, the following two definitions are equivalent, but the first is shorter.
// such that item i's price is at most item currentItem's price.
boolean b; // = " user selected menu item File | Quit"The more precise a definition, the better. Comments like "flag for loop" or "index into b" are useless; they only say how the variable is used, but not what it means.
boolean b; // true if the user selected menu item File | Quit;
// false otherwise
Related variables should be declared and described together. For example, the definition of a table should describe not only the array that holds the data but also the integer variable that contains the number of items currently in the table. In the example below, for utmost clarity tabs are used to line up identifier names and to line up the comments:
final int maxTemp = 150; // max number of temperature readings.If the comment is too long to fit nicely on the right, then put it above the declarations and indent the declarations:
int nTemp = 0; // Temperature readings are in
// temp[0..nTemp-1], where
double temps = new double[maxTemp]; // 0 <= nTemp < maxTemp
// Temperature readings are in temp[0..nTemp-1], whereReturn to table of contents
// 0 <= nTemp <= maxTemp and maxTemp is the maximum number of
// temperature readings
final int maxTemp = 150;
int nTemp = 0;
double temps = new double[maxTemp];
// An object of class Auto represents a car.Return to table of contents
// Author: John Doe.
// Date of last modification: 25 August 1998
public static class Car;
Return to table of contents
Back to Top
Back to CS100J Home