CSCI 180 (GOLDWEBER)
Spring 07: 1/26/07
Guide to a Successful Programming Style
Good style is like touch typing: it may seem counter-productive at first, but the initial effort will pay enormous dividends. After a little while, the elements of good style will be second nature. In addition to all the previously mentioned attributes that accrue from using good style, you will find that utilizing good (consistent) programming style will assist you in creating error-free programs.
1 Readability
There are a number of stylistic elements which can make a program more readable, including the use of horizontal and vertical spacing, the conventions used in declarations, etc. Each of these elements will be discussed in turn.
Keep in mind that once a program (class) is written, it is seldom read from top to bottom. Programmers in correcting or modifying a program often skip large blocks of text/code in order to find what they are looking for.
A good analogy can be made to a dictionary. Imagine if the words in a dictionary were written in normal English run-on (stream) prose style, as this handout is. What if the dictionary were not alphabetized? What if the words being defined did not appear in boldface?
As a good programmer you should strive to enhance the visual appearance of the code you write. The effort you put into this will begin to pay dividends as you eliminate errors from your code.
1.1 Indentation
Indentation is used to enable a reader to determine the statement nesting level at a glance. In order to be useful, indentation must be consistent, the number of spaces used per indentation level should be either 3, 4, or 5 spaces, and the same style of indentation should be used throughout the program. Proper indentation makes your program much easier to debug.
Fortunately the BlueJ Java programming environment automatically handles indentation for us. For good examples of the use of indentation, the interested reader is referred to the sample lab solutions.
1.2 Spaces
Normally in programming, the minimum acceptable standard for the use of spaces is that you follow normal English rules. This means that most of the basic symbols in C++ (e.g., "*", "+", etc.) should have at least one space before and one space after them, with the exceptions being that no space appears before a comma. More than one space may be used if you are aligning things on adjacent lines.
1.3 Blank Lines
Blank lines should be used to separate long, logically related blocks. This means that the variable initialization, module documentation, and main code sections should be separated by at least one blank line. Functions/methods should be separated by at least two blank lines. Similarly, within a long function body, groups of related statements may be separated from other groups by a blank line. To be effective as an element of style, blank lines should be used consistently.
1.4 Statements
Each statement should appear on a separate line; with very long lines continued on the next line indented appropriately.
1.5 Declarations
Variables should by accompanied by a documenting comment describing its use. This is particularly important with a class's instance variables.
2 Comments
In the real world both maintenance programmers and other members of a programming team rely on comments to explain the program, function or code fragment that they are reading. The comments should be brief, accurate and very precise. If a comment and the code disagree, the comment is presumed to be correct, and the code incorrect. Comments are used primarily to state what the code is doing (its purpose), while the code itself describes how you are doing it. Thus, it is only common sense that you should write the comment first (i.e., define what you are doing) before you write the code.
Comments should always start and end on the same line. This makes it easier to tell if a statement is commented out, and removes the problem of unclosed comments. Also, never put a comment in the middle of a statement or declaration unless you are commenting out a part of the statement or declaration.
Comments fall into one of the following groups:
- Program/class prologue comments.
- Function/method prologue comments.
- Declaration comments.
- Code or statement comments.
Each of these will be discussed in turn.
2.1 Program/class Prologue
The main goal of a program/class prologue is to explain the purpose of the program/class. A program prologue is similar to a function/method prologue and includes the following sections (the first three are particular to student projects):
- Your name.
- Date (or semester and year).
- Class and professor's name.
- Purpose of the program/class, i.e., an explanation of what the program/class does.
- Program input (if appropriate)
- Program output (if appropriate)
- A description of what data structures are used. (if appropriate)
- Algorithm: a general description or outline of the processing done. (if appropriate)
- Limitations or restrictions: what assumptions are made about the input data; under what conditions the program or class fails to operate properly, etc.
- Modification history: who has modified the program/class, when, and why. This section is normally started once the program or unit goes into production; thus it seldom appears in student programs.
Often when using a specialized language development environment (a program/editor specially designed for the creation of computer programs in a given language), one is provided with program/class, function/method, and instance variable templates for both code and documentation. BlueJ is one such example. It is acceptable to use the provided template. What follows is just one example of worthwhile documentation, not the sole definition of what is acceptable.
2.2 Function/method Prologue
The major reason for a function/method prologue is to explain the purpose of the function/method. A prologue should normally include the following sections:
- Explanation of parameters: these normally appear immediately after the parameter names or in the function prologue .
- Purpose of the function/method: i.e., what the function/method does.
- Algorithm: i.e., how the function/method does what it does. If a standard algorithm such as Quicksort is used, a reference rather than an explanation is preferred.
- Limitations or restrictions: what assumptions the code makes about its data; under what conditions the function/method fails to operate properly, etc. (A precise description of the preconditions and postconditions for the subprogram.)
public void PrintMembers (int memberList[], int noOfMembers) {
/****************************************************************
Purpose: Prints a list of active club members to the screen.
Algorithm: For each item in memberList [0 .. (noOfMembers - 1)],
checks whether or not the current record represents an
active member. If active, then displays the member;
otherwise does nothing.
Preconditions: Describe appropriate preconditions for the
input parameters.
Postconditions: Describe appropriate postconditions for the
function.
Parameters: memberList: array of club members
noOfMembers: number of members
***************************************************************}
2.3 Declaration Comments
Constants and variables are always commented with short, precise comments giving their purpose. These comments normally follow the variable initialization on the same line and only rarely take more than a line or two. Similarly, function/mehod parameters are always commented.
2.4 Statement Comments
Statement comments generally fall into one of the following groups:
- Comments which explain a block of code: such a comment should precede the code itself and should be indented one indentation level. The entire block of code including the comment should be separated from other blocks of code by a blank line.
- Comments which explain a statement: such a comment should follow the statement on the same line. Such comments are common in assembly code.
- end comments: such a comment uniquely identifies the component which is being ended and is essential in finding the matching while, if, for, or class. In the case of a function/method, the comment contains the name of the handler or function.
The first two types of comments can obscure the code which is being commented and if not used properly can have a negative effect on the readability of the code. Thus, code block comments and statement comments should be created carefully. Before adding such comments you should first attempt to make the code itself more understandable, by improving the identifier names used, by replacing groups of statements with helper method calls, by reducing the control complexity of the code, etc.
3 The Structure of Names
In a language like Java, names must be given to files, classes, functions/methods, variables, constants, and when using BlueJ, projects. Usually the sequence in which the names of various entities are chosen is random. This should not be the case. There is a clear advantage in choosing the names in a certain order. The remainder of this section discusses the structure of names for the different objects. After that it will become clear that the proposed sequence in naming is preferable.
3.1 Function/Method names
A function/method is (literally) called by its name which stands for a group of statements to be executed. Therefore the name should express the implied action ("Do This") by including a verb.
Different languages have different naming conventions. In C++ function names should always be capitalized. Oddly enough, in Java, the convention is to give functions/methods names whose first letter is lower case.
Examples: storeWord, displayError, showPrinterStatus, printPage,
invertMenuTitle, openWindow, drawLine, printAddress, getFirstElement,
checkMachineState, findName.
3.2 Variable names
As with all identifiers, identifiers that are the concatenation of two or more English words should have the first letter of all words after the first capitalized.
Examples: firstState, nextState, lastElement, bigWindow, homeAddress,
runningTitle, headPointer, titlePage, endOfList, maxLength, currentSymbol,
optimalLevel, screenWidth.
3.3 Constants
Constants often describe a limit within a program. In these cases it is appropriate to use the prefix "Max" in conjunction with the type name. Otherwise treat the names for constants like variable names.
Constants should always appear in all capital letters.
Examples: MAXLINELENGTH, MAXLINESPERPAGE, MAXNOOFELEMENTS, MINWINDOWWIDTH,
FASTCLICK, SLOWCLICK, DEFAULTREPEATRATE.
3.4 General Hints on Naming
The most important criterion when choosing a name is: how easily another programmer can understand the program (and not just yourself). If understanding a name was not important we could name the variables a, b, i, j, x, y, etc.
- Names must be pronounceable. Use long names without truncating the name. As a "rule of mouth": if you cannot read the name out loud, it is not a good name.
Examples: groupID instead of grpID, nameLength and not namln, PowersOfTwo and not PwrsOf2, ResetPrinter and not RstPrt.
- Use capitalization to mark the beginning of a new word within a name. This makes the name easier to parse. (The use of underscores is an alternative convention. Studies have also indicated that this style is slightly less readable.)
Examples: latestEntry, nextState, topOfStack, or latest_entry, next_state,
top_of_stack.
- Abbreviate with care. Abbreviations always carry the risk of being misunderstood; does
termProcess mean terminateProcess or terminalProcess? Usually they are also hard to pronounce (i.e.nxtGrp). Use only commonly know abbreviations, like the ID in processID. You should also only abbreviate a name if it saves more than three characters.
Examples: error and not err, name and not nam, but maxLineLength is probably better than maximumLineLength.
- Boolean variables should state a fact that can be true or false. This is easy to achieve with the inclusion of "is" in the name.
Examples: printerIsReady, queueIsEmpty, or simply done. Note how naturally this reads:
if printerIsReady {
- The more important an object is, the more care should go into choosing its name.
4 Miscellaneous Java Style Conventions
Few numeric constants should appear in your code, other than 0, 1, ' ', and nil. (i.e. No magic numbers). All other constants should be declared and named as a CONSTANT.
All selection and iteration constructs should use a begin brace ({) and an end brace (}) even if only one statement is placed inside the braces.
File translated from
TEX
by
TTH,
version 3.74.
On 26 Jan 2007, 09:37.