Five Stones Development, Inc

Application Development Services

Documentation and Coding Standards


Documentation and Coding Standards


1      Purpose   3

2      The Goal   3

3      Documentation Philosophy   4

4      Online Documentation System   4

5      Java Doc Standard Summary   5

6      Documentation Guidelines   6

7      Source Code Organization   8

8      Standards For Naming   9

9      General Techniques To Follow for Writing Clean and Readable Code   11

Compiled by Peter Morrone

Five Stones Development, Inc.

peterm@fivestonesdev.com


1       Purpose

The purpose of his document is to outline some very basic coding, documentation and naming conventions used in our projects. While this document touches on effective and robust coding practices it is in no way intended to be exhaustive.  There are hundreds of books written on that subject and that is well beyond the scope of this document.

The majority of this document is a compilation of many sources.  Primary sources include:

Macadamian Technologies Inc.

http://www.macadamian.com/codingconventions.htm

Much of this document originated from

http://www.ambysoft.com/javaCodingStandards.pdf

And also

http://www.xprogramming.com/Practices/xpractices.html

2       The Goal

Development in a team environment requires constant interaction with your teammates and with your teammates code.  An application spends the majority of its existence being maintained, not developed.  More Often than not, the code you author will be maintained by someone else. Thus, an important goal during development is to ensure that you can transition your work to another

developer, or to another team of developers, so that they can continue to maintain and enhance your work without having to invest an unreasonable effort to understand your code.

Code that is difficult to understand runs the risk of being scrapped and if everyone is doing their own thing then it makes it very difficult to share code between developers, raising the cost of development and maintenance.

Coding standards are important because they lead to greater consistency within your code and the code of your teammates. Greater consistency leads to code that is easier to understand, which in turn means it is easier to develop and to maintain. This reduces the overall cost of the applications that you create. 

This document strives to provide a lightweight set of standards such that any team member can feel comfortable reading and maintaining others code.  The conventions outlined here we successfully used on a large-scale application development project. New people were brought on board and felt very comfortable working with the code and adopting the standards defined here.

Throughout this document there are some good ideas, recommendations etc.  There are several tables in this document.   The essence of the standard is summarized in those tables.

3       Documentation Philosophy

The type of documentation that we're dealing with here is primarily class, API or method, and source code.  The only thing worse than incomplete documentation is incorrect documentation.  A developer's nature is to develop code, not to develop documentation.  When maintaining code, existing documentation is rarely maintained.  This results in old, outdated and usually incorrect documentation.

The best process is one that works with the programmers nature not against it.  This argues for stronger focus on writing clear code and less focus on documentation of poor or unclear code (as well as the maintenance of the documentation) .  Simple and clean code typically requires little or no documentation.  Meaningful and informative class, method, parameter and variable naming goes a long way toward achieving clean and readable code. That is why much of the emphasis in this document is on naming conventions and syntax.

 In the past long and descriptive method and variable names were frowned upon because of the additional typing required.  However, with today's advances in auto completion features of our editors there is no excuse to have to terse and cryptic names. Names should be as long as required to fully qualify what the variable represents, what the method does, etc. and no shorter.

There are many who adhere to the notion that there should be no source code comments.  If your source code is not easily understandable it should be re-factored, names reworked etc. to make it that way.  Then and only then should comments be used to clarify.   This should be our goal and general philosophy as we write our code, name our classes, methods etc.

For a good discussion on this see….

http://www.xprogramming.com/Practices/xpractices.html

 The reality is that regardless of how clear our code can become, we will always need to document so let’s do it in a uniform and consistent manner

4       Online Documentation System

Since we are documenting our classes and methods anyway, we may as well adhere to some industry standard documentation system so we can automatically generate API and Class Brower Documentation.

All Classes, public and protected methods, and protected member variables should have, at a minimum, a comment header formatted according to the Sun Java Doc Standard.  Java Doc is an industry standard that has been widely accepted.  It is used almost exclusively in the Java world and has been very heavily adopted into the CPP world.

Once our code it properly documented using the java doc standard we can use one of many programs to generate the documentation automatically.  We currently use Doxygen.  Doxygen is a documentation system for C and C++. It can generate an on-line (HTML) class browser and API documentation by reading the Java Doc formatted comments and evaluating the code structure.  Doxygen is free and available at

http://www.stack.nl/~dimitri/doxygen/index.html

Through the use of Java Doc comments and Doxygen we have a great online documentation system that gets automatically generated for us.  This is essential for new team members coming into a project as well as helping your team member use and maintain existing classes.

5       Java Doc Standard Summary

A documentation comment done according to Java Doc Standards starts with /** and ends with */.  In between should be the Class, Method, Member description along with 0 or more Java Doc tags.  These tags are used for identification of specific information.  The table below shows some basic tags.

Tag

Used for

Purpose

@author name

Classes,

Interfaces

Indicates the author(s) of a given piece of code. One tag per author should be used.

@exception name description

Member

Functions

Describes the exceptions that a member function throws. You should use one tag per exception and give the full class name for the exception.

@param name description

Member

Functions

Used to describe a parameter passed to a member function, including its type/class and its usage. Use one tag per parameter.

@return description

Member

Functions

Describes the return value, if any, of a member function. You should indicate the type/class and the potential use(s) of the return value.

@see ClassName

Classes,

Interfaces,

Member

Functions, Fields

Generates a hypertext link in the documentation to the specified class. You can, and probably should, use a fully qualified class name.

@see ClassName#member

functionName

Classes,

Interfaces,

Member

Functions, Fields

Generates a hypertext link in the documentation to the specified member function. You can, and probably should, use a fully qualified class name.

@version text

Classes,

Interfaces

Indicates the version information for a given piece of code.

An example of a simple method header done in Java Doc format is…

/** Sets the Text size and Forground/Background colors of the control

*

*

* @param nHeight   int: The Height of the text in twipps.  A twipp is 1/1440 of an in.  There are 20 twips in a

*                            Font Pt.

* @param colText   COLORREF: Text Color

* @param colBack   COLORREF: Background Color

* @return

*/

void OASimpleTimeCodeDisplay::SetSizeAndColors (int nHeight, COLORREF colText, COLORREF colBack)

{…

A Java Doc Comment for a member variable looks like this

/** Holds the time to run the test in milliseconds.  Value will be TEST_NOT_RUN if the test has not yet run */

ULONG m_testTimeInMS;

For information and complete java doc documentation standards see

http://java.sun.com/products//jdk/javadoc/index.html

6       Documentation Guidelines

6.1    Here are some Documentation Basics:

*         Comments should add to the clarity of your code. The reason why you document your code is to make it more understandable to you, your coworkers, and to any other developer who comes after you.  Before clarifying with a comment, try to clarify the code first to eliminate the need for a comment.

*         Avoid decoration, i.e. do not use banner-like comments. They are a waist of time.

*         Keep comments simple.

*         Document why something is being done, not just what (the what should be clear from your well structured and named code!).

6.2    Comment Types and their usage

There are three types of comments.  Documentation comments start with /** and end with */  (Java Doc Style), C-style comments which start with /* and end with */, and single-line comments that start with // and go until the end of the source-code line. In the chart below is a summary of the use for each type of comment, as well as several examples.

6.3    Commenting Routines

Here are a few guidelines about commenting routines.

Describe each routine in one or two sentences at the top of the routine. If you can't describe the routine in a short sentence or two, you probably need to think harder about what it is supposed to do. It might be a sign that the design isn't as good as it should be. Don't be tempted to explain everything in the block header. Instead, add comments in the code close to the code that it is commenting. It will be much more tempting to maintain those comments if the code changes.

Don’t comment the closing braces of if, while, for etc

6.4    Style and Layout

Layout, like goto is a religious issue with most programmers. Layout is more like the aesthetic aspect of code and that is mostly a matter of personal preference.

However, one should not forget that the fundamental theorem of formatting is that good visual layout should show the logical structure of the program.   Layout is not dealt with in this document.  There are ample tools now that can re-layout source code in seconds.  There is no reason to standardize on a particular layout style.  If you don’t like what you see, run your re-formatter.  If you don’t have one, get one.

7       Source Code Organization

7.1    Files and project organization

As a rule of thumb, files containing class definitions and implementations should contain only one class. The name of the file should be the same as the name of the class. Files can contain more than one class when inner classes or private classes are used.

7.2    Header Files

7.2.1      Include Statements

Include statements should never refer to a header file in terms of absolute path. For example, the following statement:

   #include "\code\TelephonyMgr\Include\TMPhoneLine.h"

is wrong, while:

   #include "TMPPhoneLine.h"

is right provided that the makefile or project file has the appropriate paths set-up for compilation. Also:

   #include "../include/TMPhoneLine.h"

not recommended.  It is better to put the paths in the make file so the directory structure can be re-organized without affecting code.

7.2.2      Multiple Inclusion of a header file

To avoid multiple inclusion of a header file, guarding pre-compiler code must be added to every header file.

   #ifndef _TMPhoneLine_H_

   #define _TMPhoneLine_H_

   ... Rest of Header File ...

   #endif // _TMPhoneLine_H_

For Microsoft C++ specific code, The use of the "#pragma once" should also be used to optimize compilation times. However, it doesn't replace the #ifndef guarding block.


8       Standards For Naming

                               

8.1    What Makes Up a Good Name

*          Use full English descriptors that accurately describe the variable/field/class

*          Use terminology applicable to the domain.

*          Use mixed case to make names readable. Most names use the “Capitalize the first letter or each word” rule standard with some variations as specified in the table below

*          Use abbreviations sparingly, but if you do so then use them intelligently

*          Avoid leading or trailing underscores. Names with leading or trailing underscores are usually reserved for system purposes, and may not be used for any user-created names except for pre-processor

*          Make the name as informative as possible.  For  example if a variable or method parameter holds the length of something, don’t just call it length,  call it lengthInInches.  Your coworker will love you for it.

*         Lists or collections should be named in the plural or by specifying the type of construct used.  For example, a linked list holding Car objects would be called m_cars or m_carList.

8.2    Summary of Naming Conventions Used

The following table illustrates the naming conventions used and some examples.

9       General Techniques To Follow for Writing Clean and Readable Code

9.1    Document Your Code

Remember, if your code isn't worth documenting then it isn't worth keeping (Nagler, 1995). When you apply the documentation standards and guidelines proposed in this paper appropriately you can greatly enhance the quality of your code.

9.2    Paragraph/Indent Your Code

One way to improve the readability of a member function is to paragraph it, or in other words indent your code within the scope of a code block. Any code within braces, the { and } characters, forms a block. The basic idea is that the code within a block should be uniformly indented one unit

9.3    Use Whitespace in Your Code

A few blank lines, called whitespace, added to your code can help to make it much more readable by breaking it up into small, easy-to-digest sections (NPS, 1996; Ambler, 1998a).

9.4    Follow The Thirty-Second Rule

I have always believed that another programmer should be able to look at your member function and be able to fully understand what it does, why it does it, and how it does it in less than 30 seconds. If he or she can't then your code is too difficult to maintain and should be improved. Thirty seconds, that's it. Another good rule of thumb is that if a member function is more than a screen then it is probably too long. 

9.5    Specify the Order of Operations

Use parenthesis, also called "round brackets," to specify the exact order of operations in your code.  Someone maintaining your code should not have to know the order of operations for the language to understand your code.

9.6    Write Short, Single Command Lines

Whenever you attempt to do more than one thing on a single line of code you make it harder to understand. Why do this? We want to make our code easier to understand so that it is easier to maintain and enhance. Just like a member function should do one thing and one thing only, you should only do one thing on a single line of code.

9.7    Use Accessors (Hide your member variables)

I think that Kanerva (1997) says it best: “Good program design seeks to isolate parts of a program from unnecessary, unintended, or otherwise unwanted outside influences. Access modifiers (accessors) provide an explicit and checkable means for the language to control such contacts.” Accessor member functions improve the maintainability of your classes in the following ways:

*   Updating fields. You have single points of update for each field, making it easier to modify and to test. In other words your fields are encapsulated.

*   Obtaining the values of fields. You have complete control over how fields are accessed and by whom.

*   Obtaining the values of constants and the names of classes. By encapsulating the value of constants and of class names in getter member functions when those values/names change you only need to update the value in the getter and not every line of code where the constant/name is used.

*    Initializing fields. The use of lazy initialization ensures that fields are always initialized and that they are initialized only if they are needed.

*   Reduction of the coupling between a subclass and its superclass(es). When subclasses access inherited fields only through their corresponding accessor member functions, it makes it possible to change the implementation of fields in the superclass without affecting any of its subclasses, effectively reducing coupling between them. Accessors reduce the risk of the “fragile base class problem” where changes in a superclass ripple throughout its subclasses.

*    Encapsulating changes to fields. If the business rules pertaining to one or more fields change you can potentially modify your accessors to provide the same ability as before the change, making it easier for you to respond to the new business rules.

*   Simplification of concurrency issues. Lea (1997) points out that setter member functions provide a single place to include a notifyAll if you have waits based on the value of that field. This makes moving to a concurrent solution much easier.

*    Name hiding becomes less of an issue. Although you should avoid name hiding, giving local variables the same names as fields, the use of accessors to always access fields means that you can give local variables any name you want – You do not have to worry about hiding field names because you


9.8    Minimize Member Function Visibility

For a good design where you minimize the coupling between classes, the general rule of thumb is to be as restrictive as possible when setting the visibility of a member function. If member function doesn't have to be public then make it protected, and if it doesn't have to be protected then make it private.

The table below summarizes the visibility and usage suggestions.

Visibility

Description

Proper Usage

public

A public member function can be invoked by any other member function in any other object or class

When the member function must be accessible by objects and classes outside of the class hierarchy in which the member function is defined.

protected

A protected member function can be invoked by any member function in the class in which it is defined or any subclasses of that class.

When the member function provides behavior that is needed internally within the class hierarchy but not externally.

private

A private member function can only be

invoked by other member functions in the

class in which it is defined, but not in the

subclasses.

When the member function provides behavior that is specific to the class. Private member functions are often the result of refactoring, also known as reorganizing, the behavior of other member functions within the class to encapsulate one specific behavior.

9.9    Minimize the Public and Protected Interface

One of the fundamentals of object-oriented design is to minimize the public interface of a class. There are several reasons for this:

*   Learn ability. To learn how to use a class you should only have to understand its public interface. The smaller the public interface, the easier a class is to learn.

*   Reduced coupling. Whenever the instance of one class sends a message to an instance of another class, or directly to the class itself, the two classes become coupled. Minimizing the public interface implies that you are minimizing the opportunities for coupling.

*   Greater flexibility. This is directly related to coupling. Whenever you want to change the way that a member function in your public interface is implemented, perhaps you want to modify what the member function returns, then you potentially have to modify any code that invokes the member function. The smaller the public interface the greater the encapsulation and therefore the greater your flexibility.

It is clear that it is worth your while to minimize the public interface, but often what isn't so clear is that you also want to minimize the protected interface as well. The basic idea is that from the point of view of a subclass, the protected interfaces of all of its superclasses are effectively public - Any member function in the protected interface can be invoked by a subclass. Therefore, you want to minimize the protected interface of a class for the same reasons that you want to minimize the public interface.

9.10   Don’t Use Parameterized Macros

In the past, parameterized macros were used frequently instead of simple routines. This was done mostly for performance reasons.  This is not necessary with compilers that are more modern because they can be replaced by inline routines.

Macros are very hard to debug because the compiler doesn't generate the proper symbols for it. Unless they are necessary for conditional compilation or a similar purpose, they should not be used and should be replaced by inline routines.

9.11   No magic numbers

The main body of your code should not have explicit numbers in it.  Use enum or const to give the number a symbolic name.  There are two advantages:

*          The symbolic name makes the value self documenting, obviating the need for a comment.

*          If the number is used in more than one place, there's only one thing to change - the constant definition.

Exceptions to this rule can be made for locally used variables.  For example, the following code uses a magic number (128):

{

    char buf[128];

    fgets( buf, sizeof(buf)/sizeof(*buf), stdin);

}

Because I've used sizeof() in the fgets() call, changes made to the array size are automatically reflected in the code.  Adding an extra symbol to hold the size would add unnecessary complexity.


Appendix A: Short Form Summary

Coding standards are important because they lead to greater consistency within your code and the code of your teammates. Greater consistency leads to code that is easier to understand, which in turn means it is easier to develop and to maintain. This reduces the overall cost of the applications that you create.

Commenting Basics:

*         Comments should add to the clarity of your code. Before clarifying with a comment, try to clarify the code to eliminate the need for a comment.

*         Avoid decoration, i.e. do not use banner-like comments.

*         Keep comments simple.

*         Document why something is being done, not just what.

Documentation Comments

All Classes, public and protected methods, and protected member variables should have, at a minimum, a comment header formatted according to the Sun Java Doc Standard.  This allows us to use an automatic documentation generator to create on-line (HTML) class browser and API documentation.

Commenting Styles

Class and Header File Issues

*         As a rule of thumb, files containing class definitions and implementations should contain only one class. Files can contain more than one class when inner classes or private classes are used.

*         The name of the class and header file should be the same as the name of the class.

*         Include statements should never use absolute or relative path. Put the paths in the make file.

Naming Guidelines

*          Use full English descriptors that accurately describe the variable/field/class

*          Use terminology applicable to the domain.

*          Use mixed case to make names readable.

*          Use abbreviations sparingly, but if you do so then use them intelligently

*          Avoid leading or trailing underscores.

*          Make the name as informative as possible. 

*         Lists or collections should be named in the plural or by specifying the type of construct used.

Naming Conventions