Coding Standards¶
- Coding Standards
- Scope
- Style Standards
- Technique Standards
- Sample Code
- APPENDIX A
Scope¶
This document establishes the elements of style (formatting) and technique (SW Engineering) for the use of the Java programming language within GIFT. These standards do not teach Java; developers are expected to be familiar with the language. In general, the rules outlined here are meant to improve the product and not to be overly burdensome. In some cases, exceptions to these rules will apply. For example, code that is autogenerated may not follow these guidelines. It makes no sense to expend extra effort to modify autogenerated code to adhere to coding guidelines. However, when autogenerated code is generated by GIFT developed systems, the developer should strive to make the autogenerated code follow the coding standards.
Style Standards¶
The GIFT Java coding standard is documented in the Sun Code Conventions for the JavaTM Programming Language. Exceptions and GIFT-specific standards are documented in the following subsections. In case of a conflict, the information in this document shall take precedence over the Sun Code Conventions. Programmers shall develop code consistent with the standard. Tools within the GIFT development environment shall enforce the adherence to these coding standards.
The Sun Java coding conventions originate at Code Conventions for the Java Programming Language dated April 20, 1999 at the time of writing for these GIFT Coding Standards.
Common File Names¶
Frequently used file names are shown in Table 1, and shall supersede those used in section 3 of Code Conventions for the Java Programming Language.
Table 1: Frequently Used File NamesFile Name | Use |
build.xml | Ant build file. |
README.directory-name or README.package-name | The preferred name for the file that contains specific information about a particular directory. Note that it is preferred to have a README file appended with some unique identifier (such as the directory name or package name) so that the file-system is not filled with many files of the same name but varying contents. If present, the README file should contain unique information that is not duplicated in the package.html file. If all the information in a README file can be legitimately placed in the package.html file, than no README file is necessary. |
package.html | The HTML file containing the javadoc comments for the package represented by the current directory. Javadoc will automatically incorporate this document into the package documentation it creates. |
Java Source Files¶
Java files shall have the same name as the class or interface that they contain. Capitalization of the filename and the classname shall be identical. Java source files shall use the .java file extension. No spaces shall be included in the path names or file names for any Java files or packages.
File Header¶
All GIFT Java source files shall begin with the file header conventions as outlined in Appendix A, which supersedes the header described in section 3 of Code Conventions for the Java Programming Language. The sequence shall be the Copyright header, package statement, imports, class Javadoc documentation, and the class definition.
Copyright statements are not to be removed from existing source files, but additional copyright legends may be added to the legend when code modifications exceed 25% of a given file.
Import Statements¶
Wildcard import statements shall be avoided. For example:
import java.awt.*; // AVOID THIS!
Rather, import statements shall be as precise as possible. For example
import java.awt.event;
import java.awt.frame;
import java.awt.graphics;
Import statements that are not actually required and for which no classes or interfaces are actually used shall be avoided.
Main Methods¶
Classes that are test-drivers or that form main programs shall contain a main() method. If present, the main method shall be the last method in the file. Ordinary classes should not contain main() methods that would artificially increase the dependency of the class or package on other classes or packages.
Indentation¶
Tab characters shall be avoided since different editors may treat them differently.
Comments¶
The following comment standards shall be enforced, in addition to the comment guidelines provided in: http://java.sun.com/docs/codeconv/html/CodeConventions.doc4.html. When developing comments, the Java convention is not to over comment the code. The Java commenting conventions state that you should not comment on concepts that are clearly evident in the code. That commenting guideline drives the following comment guidelines.
The following quote is from the comment guidelines [author's emphasis]:
"Comments should be used to give overviews of code and provide additional information that is not readily available in the code itself. Comments should contain only information that is relevant to reading and understanding the program. For example, information about how the corresponding package is built or in what directory it resides should not be included as a comment. Discussion of nontrivial or non-obvious design decisions is appropriate, but avoid duplicating information that is present in (and clear from) the code."
Block Comments¶
In addition to other standard Java comment style, the following comment style can be used to divide logical groupings of methods in very large classes:
/////////////////////////////////////////////////////////////// // The DBMS access routines ///////////////////////////////////////////////////////////////
Commented Out Code¶
Large sections of commented-out code should be avoided, as it hinders readability. In general, developers should rely on the source control system to remember old obsolete code.
Javadoc Comments¶
GIFT source code shall be documented using the Sun Javadoc standards. Reference Sun's Javadoc comments page for more information on Javadoc comments and style. The following sections discuss the javadoc comments that are required in all GIFT Java files amplifying the Sun documentation.
Note: The Sun Javadoc coding standard states that Javadoc comments should document when an implementation is not thread safe. This means that your comments should tell the reader when and why your code is not thread safe.
- Package Header
There will eventually be a standard.
- Class Header
A javadoc description of the class shall be included prior to each class according to the following template.
This description should be extensive enough that a developer will understand how to use this class by reading the documentation. Include code examples and embedded HTML where appropriate.
/**
* This class represents an observable object, or "data"
* in the model-view paradigm. It can be subclassed to represent an
* object that the application wants to have observed.
*
* @author [name]
*
*/
- Attribute Header
A javadoc description shall be included prior to each public instance variable according to the following templates. A javadoc description should be provided for package, protected, and private instance variables where the name does not imply the use (this is following the Sun java standard of not commenting obvious code).
/**
* The allowed error in milliseconds, associated with network timing latencies; negative values can be used.
*/
public long epsilon;
OR
/** The time in milliseconds between checking if the entity location has changed */
public long delta;
The following example would be a questionable use of commentary. It adds nothing to understanding the use.
/**
* The width dimension in pixels
*/
protected int choiceBoxWidth;
- Method Header
A javadoc description shall be included prior to each non-private method, according to the following template. A description of the method shall be included for each non-private method. If there are any parameters, all parameters shall be documented using @param tags. If the method has a return value, the return value shall be documented using the @return tag. If the method throws any exceptions, the exceptions shall be documented using the @throws tag (note the @exception and @throws tags are equivalent with @throws preferred). When providing the description, don't simply restate what is evident from reading the code. The documentation should include more than a listing of the method name and the parameter types.
The following excerpt is from the Sun Javadoc coding standard.
Add description beyond the API name. The best API names are "self-documenting", meaning they tell you basically what the API does. If the doc comment merely repeats the API name in sentence form, it is not providing more information. For example, if method description uses only the words that appear in the method name, then it is adding nothing at all to what you could infer. The ideal comment goes beyond those words and should always reward you with some bit of information that was not immediately obvious from the API name.
Avoid - The description below says nothing beyond what you know from reading the method name. The words "set", "tool", "tip", and "text" are simply repeated in a sentence.
/**
* Sets the tool tip text.
*
* @param text The text of the tool tip.
*/
public void setToolTipText(String text) {
Preferred - This description more completely defines what a tool tip is, in the larger context of registering and being displayed in response to the cursor.
/**
* Registers the text to display in a tool tip. The text
* displays when the cursor lingers over the component.
*
* @param text The string to display. If the text is null,
* the tool tip is turned off for this component.
*/
public void setToolTipText(String text) {
Javadoc comments do not need to be added for methods that override or implement other methods. This occurs when a method in a class overrides a method in a superclass, when a method in an interface overrides a method in a superinterface, and when a method in a class implements a method in an interface. However, the developer must provide javadoc comments in these cases when the overridden method's behavior is changed and the inherited documentation is incorrect. See the javadoc documentation for a description of inheriting or re-using javadoc comments. For example, copying a method header from an interface to the method that implements it is not required.
Example Javadoc method comments:
/**
* Returns <code>true</code> if and only if the current thread holds the
* monitor lock on the specified object.
*
* @param obj the object on which to test lock ownership.
* @throws NullPointerException if obj is <code>null</code>.
* @return <code>true</code> if the current thread holds the monitor lock on
* the specified object.
*/
- Constructor Headers
Constructor commentary should be provided that helps the user understand any special circumstances or requirements for the constructor. Remembering the Javadoc standard for useful comments, including comments for constructors that say "Public Constructor." or "Constructor" do not provide any additional value. For cases where construction is simple and takes no arguments, no commentary is required. As a special case, any classes that don't specify constructors and, as a result, are supplied a default constructor from Java do not need to provide commentary. Constructors that impose restrictions on constructions, have parameters, or throw exceptions must be documented. This documentation should tell the user how to specify parameters, special cases and boundary conditions for parameters, cases when exceptions can be thrown, and restrictions on construction. Don't provide commentary to satisfy process, provide commentary to satisfy users.
Units of Measure¶
Comments shall document the units of measure of attributes or parameters. The Units of Measure standard specifies what units are to be used for GIFT.
Example:
/**
* Sets the speed for the propulsion model to obtain. This method sets the desired
* speed for the tracked hull model in the desired gear.
*
* This speed denotes the maximum speed that the dynamics model should achieve if possible.
* The requested speed is still subject to all the forces in the sum of forces equations
* so that the desired speed may never be actually realized.
*
* For example, if slope or terrain type do not allow this desired speed, the maximum
* speed possible for the current configuration will be met. However, the maximum
* speed should never be sustained above this commanded speed. There may be times
* when this speed is exceeded such as when traveling down a slope (especially a steep slope)
* or when the commanded speed is less than the current speed. In the latter case,
* deceleration occurs according to the validated dynamics model.
*
* As a special case, negative speeds will be treated as a request for zero
* speed. However, a zero speed does not imply that brakes are applied. A zero speed
* on a slope, without brakes applied, may result in a hunting speed as the vehicle coasts
* down the slope and corrects for a non-zero speed. In these cases, the driver
* should apply brakes to prevent hunting.
*
* @param commandedSpeed the speed in m/s that the tracked hull is commanded to obtain.
* Negative speeds will result in a desired speed of zero.
*/
public void setCommandedSpeed(double commandedSpeed) {
Statements¶
The following formatting conventions shall be enforced, in addition to the statement guidelines provided in http://java.sun.com/docs/codeconv/html/CodeConventions.doc6.html.
return Statements¶
In general, method constructions with a single return point are to be preferred over constructions with multiple return points. However, where a multi-return construction actually clarifies the intent of the code, the multi-return construction is preferred. For example, the following method is acceptable:
private boolean isaConnectionToken(Object userToken) {
.
.
for (i=0; i<totalConnectionEntries; i++) {
connectionEntry = ConnectionManager.getEntry(i);
if (connectionEntry.openConnection()) {
localTokenList = connectionEntry.getLocalTokenList();
for (j=0; j<localTokenList.size(); j++) {
if (userToken == localTokenList.getToken(j)) {
return true;
}
}
}
}
return false;
}
}
Naming Conventions¶
The following naming conventions shall be enforced, in addition to those found in http://java.sun.com/docs/codeconv/html/CodeConventions.doc8.html.
For all name types (packages, classes, methods, ...), do not use real world equipment names when naming generic models of items. For example, do not use the name HC-7910 for a generic encryption model. Use the term atm_encryption or some other generic name. Using specific names for generic models will hamper releasability in the future.
When naming items to the coding conventions referenced above, the use of underscore ("_") is allowed only as a separator for Constants and is not used in any other item names.
When creating names, put adjectives before nouns as one would expect, for example use:
EntityObserver
UnitIterator
Rather than:
ObserverEntity
IteratorUnit
Packages¶
All GIFT package names will begin with mil.arl.gift. All package names will consist of lowercase letters. The GIFT package and directory structure shall be according to EPG SDF structure guidance.
Classes¶
The name of abstract classes should start with "Abstract", as in AbstractShape or AbstractVehicle.
The name of exception classes should end with "Exception", as in NetworkException or BehaviorException.
The name of factory classes should end with "Factory", as in CMFactory or IDFactory.
The name of type safe enumeration classes should end with "Enum", as in ForceEnum or SimulationStateEnum.
The word "Singleton" shall not be used in a class's name. This is not used in case the class is later refactored and it is not a singleton, or converts to using Composition services to get the singleton instance.
Interfaces¶
Developers are encouraged to use active descriptive names for interface classes. Examples include descriptive nouns (e.g., EventListener, Comparator) or adjectives derived from verbs (e.g., Tickable, Runnable, etc.).
Methods¶
Converter methods that return a representation of the instance in a different object type should start with "to", as in toString().
Getter methods that access a member of a class should start with "get", as in getCount(), in conformance with the Java Bean design patterns for properties. As much as possible, the name of the method should exactly reflect the name of the member variable being accessed. An exception to this rule is described below for Boolean getter methods.
Setter methods that set a member of a class should start with "set", as in setCount(), in conformance with the Java Bean design patterns for properties. (See section 8.3.1 ("Simple properties") and section 8.3.2 ("Boolean properties") of the JavaBeans version 1.01 specification (July 24, 1997) located at http://java.sun.com/developer/onlineTraining/Beans/bean01/.). As much as possible, the name of the method should exactly reflect the name of the member variable being modified.
Methods that return Boolean values should start with "is", "has", or other true-or-false-returning 3rd-person verb phrases, as in isRunning(), hasFinished(), or canMove().
Special Comments¶
The comment @review may be used in a comment to flag something that is bogus but works. The comment @fix may be used to flag something that is bogus and broken. The guidance supersedes the guidance provided in http://java.sun.com/docs/codeconv/html/CodeConventions.doc9.html. Note that these types of comments shall only be used within the engineering software baseline, and shall be removed (with the offending code repaired) prior to code being submitted for integration.
Acronyms¶
Common acronyms such as XML, GIF, GUI, ID, URL, etc. shall appear in all identifiers using uppercase. This applies to design, code, and data. Identifiers comprised of compound words shall represent the acronyms in uppercase, such as XMLFile and imageToGIFTranslator. An exception to this rule is a package name, which always appears in lowercase. Another exception to this rule is a variable name, which always begins with a lowercase letter. To avoid mixed case acronyms in variables, it is preferable to not begin a variable name with an acronym (i.e., theGUIThread is preferable to gUIThread).
Enumeration Value Names¶
The following section provides a naming standard for the "name" of a Common Enumeration name/value pair. This standard is meant to provide a consistent naming convention across all of GIFT, thus improving readability and maintainability. Common Enumeration names within a name/value pair must adhere to the following standards:
Enumeration Names must start with an alphabetic character: [a-zA-Z]
Enumeration Names may ONLY contain alphabetic characters, numbers, or underscores ('_'): [a-zA-Z0-9_]
Class Member Layout¶
Class members should be laid out in the following order (from top to bottom):
- Static fields
- Class (instance) fields
- Static block
- Constructors: No-arg constructor, if present, should be first. Additional constructors, if they are needed, should follow. When multiple constructors are defined, they should be listed in order of increasing complexity (in terms of number of arguments), with the least complex at the top and most complex at the bottom.
Any additional methods, should be placed below the constructor(s)
Technique Standards¶
The following programming techniques shall be used within all GIFT Java files to improve baseline performance or quality.
Method Visibility Recommendations¶
In general, methods within a class should have the most restrictive visibility possible. Private visibility is preferred over protected, which is preferred over package (i.e., no visibility modifier), which is preferred over public.
Equality, HashCode, Comparables and Comparators¶
Classes that override the java.lang.Object.equals() method must satisfy the contract for the java.lang.Object.hashCode() method as described in the Java documentation for java.lang.Object.hashCode(). In general, this means that when you override java.lang.Object.equals(), you will usually override java.lang.Object.hashCode() such that it continues to meet its contract.
Classes that implement the java.lang.Comparable interface must do so consistently with the class's implementation of equals().
Class Invariants¶
Consistent with good object-oriented practice, classes should enforce and sustain class invariants. For example, using public constructors and public methods, an instance of a class should always remain in a self-consistent state. Where possible, public constructors for a class should only allow the construction of valid and consistent instances. Where possible, overloaded constructors for a class should chain together so that enforcement of instance consistency can occur in only one place.
Error Handling¶
The GIFT error handling policy is described in the GIFT Error Handling Policy. Error handling techniques used on GIFT are exceptions and assertions.
Exceptions¶
A description for using exceptions is described in the "Exceptions and Their Use" section of the GIFT Error Handling Policy. The policy for using exceptions in GIFT is summarized in the "Policy Summary" section of the GIFT Error Handling Policy.
Assertions¶
A description for using assertions is described in the "Assertions and Their Use" section of the GIFT Error Handling Policy. The policy for using assertions in GIFT is summarized in the "Policy Summary" section of the GIFT Error Handling Policy.
Console I/O¶
A few guidelines for the use of console I/O commands can be found in the Performance Guidelines Checklist. In general, developers should use message logging and never use System.out.println as a method of debugging or notification.
Use of Threads¶
The GIFT threading policy is described in GIFT Java Threading Policy.
Deprecated Interfaces¶
Developers should avoid the use of interfaces that have been deprecated. Developers shall not ignore deprecated warnings and should establish an approach for replacing reliance on deprecated interfaces. Developers shall get architectural approval for using deprecated interfaces when no alternative is found, document the justification of these interfaces in the code, and warn clients. Developers shall not disable any tool that warns about the use of deprecated interfaces.
As stated in Sun's guidance on deprecation (see below), when deprecating methods or classes a comment shall be included to tell the user if there is an alternate method, when the method will be deleted, and if there is not alternate method why there isn't one.
For example:
@deprecated Use methodXYZ() instead. Will be removed at end of buildX.
Reference How and When to Deprecate APIs for more discussion on deprecated capabilities.
Developers should use the Java capability of marking their own interfaces as deprecated when they plan to upgrade their interfaces.
Use of Collections¶
Using collections in interfaces places additional burdens on developers. Considerations for the developer include documentation, thread safety, and scope. For collections that are present in APIs, or as part of an interface used by other programmers, full documentation needs to be included on the contents of the collection. This includes any description of keys or contents and what the client should expect to be contained in the collection. In addition, any collections used in the interface must use the most abstract type possible. For example, specify the use of a List or Collection rather than a Vector whenever possible in an interface. This hides the implementation from the user and allows for growth or changes while minimizing impact on clients. In other words, if you use Collection rather than Vector, you can easily change to using a HashMap internally later for a new capability without impacting existing clients. This also extends to internal use as well. Internal use, that is the implementation behind the interface, should use higher collection abstractions as much as possible for the same reason. Also, any use of collections must consider thread safety needs and the potential requirement to synchronize collections.
Type Safety¶
Where ever possible, developers should design using type safe objects rather than untyped interfaces. Specifically, developers should refrain from using Strings when a type safe object can be used for reasons of compile-time error checking, runtime robustness, runtime performance, and extensibility (i.e., through inheritance).
Sample Code¶
The following is an example of a Java class that is representative of good coding practice.
Example Java Class
/*
* File Name: LoSResult.java
*
* Classification: Unclassified
*
* Contract Number: W911QX13C0027
*
* This work was generated under U.S. Government contract and the
* government has unlimited data rights therein.
*
* Copyrights: Copyrights 2014.
* Dignitas Technologies, LLC.
* All rights reserved.
*
* DISTRIBUTION STATEMENT A: Approved for public release; distribution is unlimited
*
* Organizations: Dignitas Technologies, LLC.
* 3504 Lake Lynda Drive, Suite 170
* Orlando, FL 32817
*/
package mil.arl.gift.common;
import java.util.Map;
import java.util.HashMap;
import javax.vecmath.Point3d;
/**
* This class is used to provide LoS query results
*
* @author mhoffman
*
*/
public class LoSResult {
/** the visibility value for a Los Result to be considered clear LoS */
private static final double CLEAR = 0.7;
/** container of the LoS query locations to visibility percent */
private Map<Point3d, Double> locationsToVisiblity;
/** this is an example of a static block before the constructor(s) */
static {
locationsToVisiblity = new HashMap<>();
}
/**
* Default constructor
*/
public LoSResult(){
}
/**
* Class constructor - set attributes
*
* @param locationsToVisibility – results of an LoS query
*/
public LoSResult(Map<Point3d, Double> locationsToVisiblity){
this.locationsToVisiblity = locationsToVisiblity;
}
/**
* Check whether or not the location is included in the LoS result
*
* @param point – the point to check for
* @return boolean – is the point including in the LoS result
*/
public boolean hasResult(Point3d point){
return locationsToVisiblity.contains(point);
}
/**
* Check whether or not the location has a clear LoS result
*
* @param point – the point to check for
* @return boolean – is there a clear LoS result to the point
*/
public boolean isClear(Point3d point){
double visibilityValue = locationsToVisiblity.get(point);
// this is an in-method comment
boolean isClear = false;
if(visibilityValue >= CLEAR){
isClear = true;
}
return isClear;
}
/**
* Return the collection of the LoS query locations to visibility percent
*
* @return Map<Point3dData, Double> - the LoS query results
*/
public Map<Point3d, Double> getLocationsVisibility(){
return locationsToVisiblity;
}
@Override
public String toString() {
StringBuffer sb = new StringBuffer();
sb.append("[LoSResult: ");
sb.append(", locations = {");
for(Point3d data : locationsToVisiblity.keySet()){
sb.append(data + " : "+locationsToVisiblity.get(data)+", ");
}
sb.append("}");
sb.append("]");
return sb.toString();
}
}
APPENDIX A¶
Data Marking Portion of the GIFT Java Coding Standard
1. This section provides information concerning the proper marking of GIFT software and technical data. Establishing a consistent policy is essential to meeting our responsibility as we develop new, and reuse previously (Government) procured artifacts. Proper marking also allows the automation of certain portions of the access and distribution process thus minimizing required personnel efforts.
2. Marking applies to both software and technical data, as defined below:
a. Software: Defense Federal Acquisition Regulation System (DFARS) defines software as computer programs, source code, object code, algorithms, flow charts, and formulas. DFARS defines software documentation (in databases, user/owner manuals, and operating instructions) as technical data.
b. Technical Data: Recorded information of a scientific or technical nature, but not including computer software of information incidental to contract administration, such as financial or management information. Technical data is not the item or process itself; rather it describes an item, component or process (i.e., how to maintain, use operate, modify or even manufacture an item component or process).
3. Five essential items of information, explained in the following paragraphs, included in the marking of Government-procured software and technical data are:
Copyright
Government Rights
Classification
Distribution Instructions
Modification
The inclusion of the information above is essential to a complete marking of technical artifacts.
- Copyright: As a first step, there is a need to clarify the difference between ownership of a work and Government right to use the material. U.S. law and policy separates the ownership of software and technical data from the Government’s right to use the software and technical data. The company, companies or person that creates the product retains the ownership of software and technical data.
All GIFT software should include any (intact) legacy copyright within the software source code comments or the technical data artifacts. For example:
Copyright 2002, The XYZ company: All Rights Reserved
- Government Rights: The Government obtains rights to software and technical data within the context of a contractual effort. For the most part, rights are a fall-out of the work performed. Greatest rights arise when the Government funds a development exclusively. Lesser rights arise if there is mixed funding. The most restricted rights occur when the development was at private expense. Unless specifically stated otherwise in the contract, the Government has Unlimited Rights to GIFT software and technical data.
Unlimited Rights apply to both GIFT technical data and software. This is the broadest right the Government can obtain and is the next best thing to a title. Unlimited Rights is the right to use, reproduce, modify, and disclose to anyone, in any manner for any purpose. This includes reverse engineering or giving technical data and software to a competitor for commercial purposes.
- Classification: The classification (unclassified and classified) of the software and technical data ensures that no one creates an inadvertent security violation. GIFT is being developed as an unclassified system, but there is a requirement (P3I) to include the ability to run classified data. In this case, it is important that each component be clearly marked. As a general rule, mark all things that are unclassified as unclassified. The marking serves as a reminder.
- Distribution Instructions: All Software and technical data should be marked IAW DOD Directive 5230.24, "Distribution Statements on Technical Documents" dated 18 March 1987. Use Distribution A (authorizes unlimited public release) for those items that are available to the public. Mark those items with military content as Distribution D (approved for Department of Defense and U.S. DOD contractors only). If there is question on the implementation, raise it to your development and/or Government counterpart.
- Modification: In the case of an existing artifact being modified, the original markings should remain intact. In the event the artifact is substantively modified, the "Modification" section of the header should be filled out (or added) to convey the appropriate information in the Copyright, Government Rights, Classification and Distribution Instructions sections.