Style Guide

geWorkbench Developer Style Guide

There are various good style guides out there on the Internet, this document is meant to focus on the issues that are more relevant to the current code base and development activity of geWorkbench. While it is not practical to enforce the style over the legacy code, new development should follow the guide line described here. Any comments are very welcome.

  • Remove dead code. This includes: unused local variables, unused private members, unused public members, out-of-date comments, unused classes/files, unless you have specific reason to expect to use it soon or as part of unfinished development.
  • If a local variable is adequate to serve your purpose, do not make it a member variable.
  • If a private member serves your purpose, do not make it public or default or protected.
  • If the class is not intended to be extended, declare it as final - unless those require by geWorkbench framework not to be final.
  • If the method parameter is intended to be read only, declare it as final.
  • Name classes, variables, and methods what they really are or really do. If you cannot name your class as a noun, something is wrong with your design; if you cannot name your method as a verb, something is wrong with your design.
  • If one java file is over 1000 lines, the design deserves very careful scrutiny.
  • If class A refers to class B, and at the same time class B refers class A, the design needs scrutiny.
  • Refer to the object by a proper interface instead of implementation class when possible.
  • Immutable class is preferred. Particularly, do NOT implement setters for your class if you are not sure why it is necessary.
  • Clean up and organize imports to avoid unnecessary building dependency and to make dependency more explicit: (ctrl+shift+o in eclipse)
  • Format code (ctrl+shift+o in eclipse, unless it makes it hard to keep track of the changes)

Project Structure

This section describes the directory structure of the project. The root directory structure contains eclipse project file, the java.policy file, the build.xml ant build file, and the following subdirectories besides other contents:

  • _all - out of date stuff - to be removed.
  • components - The top-level directory for geWorkbench components.
  • data - Sample data files for the project.
  • lib - Library files for core geWorkbench.
  • src - Source code for core geWorkbench.

Each component is in a subdirectory of the components directory. It contains an eclipse project file and its directory structure is as follows:

  • lib - Library files depended on by this component.
  • src - Source code for the component.

Note that the components can depend on the core classes (those defined in ./src) and the core libraries (those defined in ./lib). However, components cannot depend on each other, and the core classes cannot depend on components.

Creating a New Component

A new component should be added as a new subdirectory of components. The subdirectory should be given a simple, descriptive, lower-case name. It should contain src and lib directories. Most importantly, the component must not depend on the classes or libraries of any other component, nor should another component depend on it. Also, the core geWorkbench classes should not depend on its classes or libraries.

Coding Standards

The coding standards outlined by Sun are observed. Here are some of rules that are particularly important to us:

Capitalization

Constants must be in all-capitals, with underscores between words:

public static final int MAXIMUM_FILES = 100;

No other identifiers may contain underscores but constants. Class, interface, enum and annotation names must be capitalized, with all subsequent words also capitalized:

public class SampleClass extends AnotherSampleClass {

Variable and member names must have their first letter lower-case, and subsequent words capitalized:

private String fieldName;
private abstract void processFile(File file);

Some developers differentiate between method variables and class members by prepending m_ or just _ to member names. This is not a standard practice, so is not observed. Identifiers in property files are all lower-case with periods separating words:

maximum.files=100

Type wildcards in generics must be a single capital letter:

public interface Generic<T, S extends Serializable> {

Annotations

Annotations can either appear on the same line as their associated declaration, or on the line before it:

@Subscribe public void receive(Integer value) {

@Script(dependencies = {STATE_UNINITIALIZED, STATE_COMPLETE}, result = STATE_INITIALIZED)
public void initialize() {

Variable Naming

Variables should be given verbose names, even if they are only used in relatively small code blocks. Using the auto-complete functionality of modern IDEs makes compliance with this rule painless. Exceptions are simple index variables, such as those introduced in for(;;) statements:

for (int i = 0; i < 100; i++) {

Braces

All if, while and similar block structures must be surrounded by braces, even if the body of the block consists of only one statement:

if (index < 100) {
    System.out.println("index= " + index);
}

No Shortcuts

Java provides some C-style shortcuts, such as the ++, += and ?: operators. The ++, += operators can be used by themselves (for example, ++ is often used in a for statement) but they should not be included in other statements. The ?: operator should only be used very sparingly, usually in statements that construct strings. Here is an example of a bad use of ++:

while (i < 100) {
  System.out.println("i= " + i++);
}

This is preferred:

while (i < 100) {
    System.out.println("i= " + i);
    i++;
}

This is an acceptable use of ?::

boolean available;
...
System.out.println("The file is " + (available ? "available" : "unavailable") + ".");

However, it is a safe bet to never use ?:.

Tabs

A tab-width of 4 should be used.

Code Documentation

Code must be documented using the Javadoc standard. All classes, interfaces, enums and annotations must have an introductory Javadoc explaining its purpose. All public methods must also have explanatory Javadocs. Methods that perform non-trivial operations should have normal comments (not Javadoc) that explain the code. Such comments should precede the line (or lines) of code that they describe. For example:

/**
 * Shuts down the componentRegistry (and terminates any pending aysnchronous dispatches).
 */
public void shutdown() {
    // Iterate through all active synch models
    Collection<SynchModel> models = synchModels.values();
    for (SynchModel synchModel : models) {
        // Shut down the synch model
        synchModel.shutdown();
    }
}

Packages

Package names should follow the inverse-domain rule. If the domain of your organization is

subdomain.domain.tld, then the package structure should be rooted at tld.domain.subdomain.

Capital letters or underscore characters should never appear in package names.

Otherwise, the organization of packages is left up to the developer.