LVG Java Coding Standard

NLM/NIH

(Draft)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Version Number: 1.0

Last Updated 05/17/00

 

 

Table of Contents

1. Introduction 3

1.1 Rational 3

1.2 Scope 4

2. General Mandate & Guidelines 5

2.1 Code Layout 5

2.2 Comments 7

2.2.1 General Commenting Guidelines 8

2.2.2 File Prolog & Comments 8

2.3 Declarations 9

2.3.1 Variables 9

2.3.2 Methods 9

2.3.3 Classes 9

2.4 Flow Control 10

3. Naming Conventions 12

3.1 General 12

3.2 Directories 12

3.3 Packages 13

3.4 Files 13

3.5 Classes 13

3.6 Methods 14

3.7 Variables & Parameters 15

3.8 Class Data Members 15

3.9 Constants 16

4. File & Class Prolog 16

4.1 Standard File Prolog 16

4.2 Java file Prolog Sample 17

4.3 Java Class Prolog Sample 17

4.4 Descriptions 17

APPENDIX A - Illustration of LVG Java Standard Coding Style 19

APPENDIX B - Abbreviation of Naming convention Style…………………………….21

 

1. Introduction

Think about musicians. There are only eight notes in the scale - no more, no less. In addition, notes within a scale can only be combined in certain ways. Most random combinations of notes or rhythms are mere discordant noise rather than music.

Thus, in order to produce music, a musician must follow a very constrained form. Has this led to any lack of music? Absolutely not. Following this constrained form, and working within its limitations, has allowed musicians to create everything from subtle tribal rhythms to classical music to rock and roll, and every other type of music you can mention.

Thus, instead of limiting musical expression, accepting a constraining form and working within its limits has had the exact opposite effect by allowing musicians the freedom to create without worrying about extraneous details. As long as a musician stays within the constraints, he or she doesn’t have to worry about whether or not some combination is music or noise. By staying within a framework of what is accepted as music, musicians can concentrate instead on their art. That is, by accepting the framework as a starting point, musicians can quit thinking about the framework and concentrate instead on what they are trying to express.

The exact same concept applies to software development. Writing code within a constrained style standard frees the developer from having to decide again and again how the code should look on the page, and allows him or her to concentrate instead on the code itself. That is, by accepting the style as a starting point, the developer can quit thinking about style issues and concentrate instead on what he or she is trying to express.

1-1. Rationale

"Remember, a primary aim of writing code is to make its meaning clear to the next person reading it - and that person just might be yourself a few years hence." Stroustrup, The C++ Programming Language, Third Edition, pp. 508.

All code must either evolve or die. If you want your code to survive and be useful, then you must follow a clear and consistent style/standard so that your code can evolve gracefully.

Following a clear and consistent style helps ensure that code is easier to read. Code that is easier to read is easier to understand and maintain. Code that is easier to understand and easier to maintain is code that will be better able to withstand the stress of evolution.

Code that is messy in appearance or difficult to read is not good code. And it may very well be the code that comes back to haunt you over and over again like a recurring nightmare.

If you fail to follow a clear and consistent style/standard, then you will inevitably end up with a coding mess that no one else can understand. This code will be shoved off into a corner where no one else has to deal with it, and you will be stuck with handling the mess every time it needs to be modified. Some may mistakenly think of this as job security, but in reality it is only lack of professionalism. If your code is clear, clean and easy to work with, then you can share the work of evolving it with others. Your time will be freed to write more clear, clean, easy to work with code, instead of being stuck forever with the same old ugly mess in front of you. Take the time now to think seriously about what’s really in your best interest, to say nothing about your professional obligations to your coworkers and employer.

Good code, code that is clear, clean and easy to understand, is in everybody’s best interest, and is the only product that is appropriate for professional developers. Producing good code allows you to take pride and enjoyment in your work, and should always be your primary goal.

In order to meet a primary goal, we sometimes must sacrifice lesser goals. For instance, each of us has our own ideas about how our code should look. However, if every developer follows his or her own individual style/standard, no matter how perfect it may be, the development team as a whole loses the benefit of having all code written in a single, clear, consistent style/standard.

Getting group agreement on a coding style/standard is never easy. In fact, it is one of the more difficult tasks in software development. This is so because writing code is still, for all the science that may be involved, very much an art produced by individuals. Each developer may feel handicapped by having to follow a style/standard that is not his or her own, but we must all accept the fact that we work on a team. Sometimes this means we have to do what is best for the team, rather than what we might individually prefer. Professionals accept this fact and deal with it.

There is a popular engineering proverb that says "Form is liberating". Truer words were never spoken. Do not fall into the trap of confusing chaos or anarchy with freedom of expression.

1-2. Scope

This document specifies the Java coding style/standards to be used for all developed, deliverable code on the NIH/NLM LVG projects. It does not apply to non-deliverable code such as test drivers, but it is highly recommended that these standards be followed for all developed LVG code.

This document includes "Java language Standards" (hereafter referred to as "standards"), "programming rules", and "style rules". "Java language standards" are specifically language-oriented (for example, "goto prohibited"); programming rules" mandate how certain language constructs are used (for example, naming conventions); and "style rules" pertain to the formatting of the code (for example, indentation). Within each category, there are mandatory and guideline components. Mandatory items cannot be violated (i.e., violation of a mandatory item results in automatic rejection of the software turnover); guidelines may be violated under a written approved waiver by a project technical leader.

A formal waiver process is in place and may be used when circumstance dictate, but is strongly discouraged. Any standard or rule in this document may be violated if an appropriate waiver is approved.

2. General Mandate & Guidelines

It is the responsibility of all LVG projects developers to know and apply this Java Style Standard to their own work. Code that does not conform to this standard shall not be reviewed. If a review is scheduled and it is determined that the code does not conform to this standard, then the review shall be postponed until the code is in conformance. The intent of this rule is to avoid wasting time in review sessions debating style issues. This will allow the review process to concentrate on the code instead.

2.1 Code Layout

Guideline: Make sure the layout of the code is clear and easy to read.

Mandatory: None.

Guideline: None.

Mandatory: Use 4 space as an indentation level.

Guideline: Use Courier font.

Mandatory: Use a fixed-width font.

Guideline: Don’t use indentation deeper than 4 levels.

Mandatory: None.

Guideline: None.

Mandatory: Multiple statements on a single line are prohibited.

Guideline: None.

Mandatory: 79 character or less for the length of lines.

Guideline: Align variable names, = signs, and values in columns.

Mandatory: Order declarations with initialized variables first.

The following is an example of good layout:

public class Retirement

{

Public static void main(String[] args)

{

double ballance = 0;

int years = 0;

double goal;

double interest;

double payment;

// read in goal and payment information

goal = Concole.readDouble

("How much money do you need to retire?");

payment = Console.readDouble

("Interest rate in % (ex:use 7.5 for 7.5%);")/100;

while(balance < goal)

{

balance = (balance + payment) * (1 + interest);

years++;

}

System.out.println("You can retire in " + years + "years.");

}

}

 

The following is an example of bogus layout:

public class Retirement

{

Public static void main(String[] args)

{

double ballance = 0;

int years = 0;

double goal;

double interest;

double payment;

goal = Concole.readDouble

("How much money do you need to retire?");

payment = Console.redDouble

("Interest rate in % (ex:use 7.5 for 7.5%);")/100;

// read in goal and

//payment information

while(balance < goal)

{

balance = (balance + payment) * (1 + interest);

years++;

}

System.out.println("You can retire in " + years + "years.");

}

}

 

2.2 Comments

The importance of comments cannot be emphasized enough. Every file should have an introductory section that summarizes the contents of the file (prolog). Every class definition and method should have an introduction. Within each function, all non-obvious variable declarations should be commented. Every logical section of the method (function) should be separated and commented, as needed.

Comments are mandatory for:

2.2.1 General Commenting Guidelines

++i; // increment i

2.2.2 File & Class Prolog Comments

Each class declaration (e.g., in a prolog) shall be preceded by a brief comment describing the intended use of the class. This comment also shall specifically include any special information about limitations on, or assumptions.

Anything that can be enforced by the compiler shall be so enforced rather than relying on a comment. For example, suppose that the destructor for a class is only to be invoked by another member function under a certain condition. The condition cannot be enforced by the compiler, but by making the destructor private we can at least ensure that no one outside the class can use it inadvertently.

There are certain information that should be put into file prolog comments in source files.

The file prolog is intended to be read by users and maintainers of the code. The file prolog should be related to proper usage, i.e., how the class should be used, what conditions the class assumes, and what limitations may apply to its use. That is, as per the previous code sample. In additional, coding notes should be provided. For example, prolog might indicate why a particular algorithm was chosen, and what conditions might lead to another algorithm as a better choice. This is also a good place to note the evolution originally envisioned for the code, i.e., if enhancements are planned for later, noting them directly with the code to be enhanced ensures that the code and the plan are at least in close physical proximity.

2.3 Declarations

2.3.1 Variables

 

2.3.2 Methods

2.3.3 Classes

class Good

{

constants

constructors()

public methods()

protected methods()

package scope methods () //default

private methods()

Instance variables

Static variables

};

 

 

 

2.4 Flow Control

 

Switch(value)

{

case LIVE:

SomeFunc(); // Bogus: falls into next case

case DIE:

AnotherFunc();

break; // Good

case BREATHE:

YetAnotherFunc();

// Fall into next case // OK: explicit comment

case COUGH:

SomeFunc();

break;

default: // Good: default is required

HandleError();

break;

}

// Bad way

if(count > 0)

{

amount = FigureAmount(count);

}

else if(count < 0)

{

amount = SpecialCase(count);

}

long average = amount/count; // What if count == 0?

 

// Better way

if(count > 0)

{

amount = FigureAmount(count);

}

else if(count < 0)

{

amount = SpecialCase(count);

}

else

{

// count cannot be zero

Error();

return; // not recommanded

}

long average = amount/count; // OK, can’t get here if count is zero.

 

if(condition)

{

single-line action;

}

Consistently following this guideline will prevent the common mistake of adding an additional statement to the single-line action, at the same indentation level, and expecting it to be part of the compound statement. That is:

if( transferApproved )

CreditAccount( acct1, amount );

is likely to evolve into the coding error:

if( transferApproved )

CeditAccount( acct1, amount );

DebitAccount( acct2, amount ); // NOT part of compound statement!

Whereas, the more clearly coded:

if( transferApproved )

{

CreditAccount( acct1, amount );

}

is much more likely to evolve into the correctly coded:

if( transferApproved )

{

CreditAccount( acct1, amount );

DebitAccount( acct2, amount );

}

while(index++ != 0); // Bad

while(index++ != 0) // Good

{

// Intentionally empty block

}

if(a < b < c) // Huh? Is ((a < b) < c)

if(a & b < 8) // What? Is (a & (b < 8))

3. Naming Conventions

3.1 General

3.2 Directories

3.3 Packages

3.4 Files

<ClassName><extension>

where

<ClassName> is the same as the name of the first class contained in the file. and

<extension> is ".java"

 

3.5 Classes

Examples of good names:

class MyClass

{

};

Examples of bad names:

class Bad_Class // underscore

{

};

 

3.6 Methods

Examples of good names:

double GetBonus(int performanceRating);

void Meditate(int listOfProblems);

 

Examples of bad names:

double getBonus(int performanceRating); // lower case

double Get_Bonus(int performanceRating); // underscore

double get_bonus(int performanceRating); // lower case and

// underscore

3.7 Variables & Parameters

Examples of good names:

long amount; // variable

int GetNextValue(int curIndex, int restart); // params

Examples of bad names:

long Amount; // upper case

int GetNextValue(int cur_Index); // underscore in param

char[] nameBuffer = new char[MAX_NANE_SIZE]; // Bad. Forgot

// space for null

// terminator.

char[] nameBuffer = new char[MAX_NAME_SIZE + 1]; // Good!

char[] nameBuffer = new char[10]; // Magic number Bogus

3.8 Class Data Members

Examples of good names:

long face_;

short attentionSpan_;

Examples of bad names:

long face; // no trailing underscore

short attention_Span_; // words separated by an underscore

3.9 Constants

Examples of good names:

final int MODEL 911

final int MAX_SPEED 55

 

 

Examples of bad names:

final int model 911 // lower case

final int MaxSpeed 55 // mixed case and no underscore

 

 

 

4. File & class Prolog

4.1 Standard File prolog

 

4.2 Java file prolog sample

/************************************************************

* File: Template

*

* Author: LVG Developer

*

* Description:

*

* History:

* 01/01/00, [name], Initial creation

*

* Notes:

*

* Waivers:

**************************************************************/

4.3 Java class prolog sample

//--------------------------------------------------------------

// create a new class for ...

//--------------------------------------------------------------

 

4.4 Descriptions

Certain information should be provided in the file prolog. They are detailed as follows:

 

Appendix A - Illustration of LVG Java Standard Coding Style

The standard coding style that shall be followed in all development at LVG is what is known in the literature as the extended style. This is a widely used style that is easy to follow and easy to read. Following is a brief, generic sample illustrating the appearance of the extended style as applied to each type of control flow structure.

Public static main(String[] args)

{

// Order declarations with initialized variables first.

// Leave one indentation level between type names and variable names.

// Align variable names, = signs and values in columns.

T var1 = value1;

T var2 = vale2;

T var3;

// note blank line separating declarations from code

if(condition1)

{

T var4 = value; // very local variable

condition1 true action;

}

else if(conditionN)

{

conditionN true action;

}

else // all conditions false

{

conditions false action;

}

// note blank line separating independent code blocks

for(init; condition; increment/decrement)

{

body;

}

while(condition)

{

body;

}

switch(constant expression)

{

// note blank line between each case

case value1:

action1;

break;

case valueN:

actionN;

break;

default:

default action;

break;

}

}

Notice how clean this sample appears on the page. An opening brace on a line by itself provides a clear visual demarcation between the condition test and the code being executed. Having both braces aligned at the same indentation level makes it very easy to see the limits of the enclosed code, and to spot missing braces. A blank line separating independent blocks of code makes them visually independent too.

 

 

Appendix B - Abbreviation of Naming Convention Style