Skip to main content
Jump to: navigation, search

ESF coding rules

Rules organisation

To ease the rules understanding, a classification has been made to organise them. Thus, each rule has an identifier, prefixed by its category.
The different categories are:

  • NAME: Rules related to the naming of the elements
  • FORM: Rules defining the format of the code and its presentation
  • TIPS: Tips and tricks, best practices, etc.
  • COMM: Rules dedicated to the comment content and format
  • ARCH: Architecture rules, defining how the product components, features and plugins, must be build and configured

Rules application

There is no perfect rules referential. These rules can only have an added value if there are shared and applied. The main objective is to build a code base which can live, be maintained and understood by any contributor, and not only its author.
In some specific cases, it can append that a rule can't be respected, but this must be explained and well-argued in the code comments.

Finally, as the rules live with the project, some existing modules may not respect new rules. It's the responsibility of any contributor to correct a file when he has to work on it, and this must be a part of the review process.

Rules repository

Naming category

General

  • NAME-01

The names of classes, methods, variables, must not be too long (50 characters max.).

  • NAME-02

The code is in English. The attributes, methods, classes, etc. names must be in English.

  • NAME-03

The accented characters or any characters specific to a country or an alphabet are forbidden.

Files

  • NAME-04

A source file is strictly named as the public Class that it contains, including the case.

  • NAME-05

A source file has the .java extension, and the compiled files have the .class extension.

Packages

  • NAME-06

A package name contains only lower case letters, separated by dots.
It's recommended to use short words, concatenations and abbreviations instead of group of words to limit the size of the package names. The common acronym could also be used.

  • NAME-07

The package names must begin by org.polarsys.esf.

  • NAME-08

The package name must strictly correspond to the system folders tree, from the source folder root.

Classes

  • NAME-09

A Class or Interface name contains only letters, begins by an upper case letter, and respect the CamelCase syntax.
The name must be a word or a group of words which describes the Class role and services. Moreover, using non alphabetic or numerical characters is forbidden. For example, to rename a Class which extends a parent Class by adding only a numerical suffix doesn't allow to understand its behaviour differences. This doesn't ease the code readability and maintainability.

  • NAME-10

The acronyms are forbidden, except for the following list of common elements: ASCII, HTML, SQL, URL.

  • NAME-11

Some Classes or Interfaces must be prefixed or suffixed to highlight their type or a design pattern used. For example:

IElement For an Interface
AbstractElement For an abstract Class
ElementNotFoundException For an Exception
ElementSingleton For the singleton design pattern
ElementFactory For the factory design pattern

Methods

  • NAME-12

A method name contains only letters, begins by a lower case letter, and respect the CamelCase syntax.
The name must be a word or a group of words which describes the method role and behaviour. Moreover, using non alphabetic or numerical characters is forbidden.

  • NAME-13

A method will perform something, the first word is thus generally a verb.

  • NAME-14

The accessors methods of a property have a normalised prefix:

get Getter of a property
set Setter of a property
is Getter of a boolean property
add To add an element to a collection property
remove To remove an element from a collection property
  • NAME-15

The accessors of collection property must have a name ending by a plural. The indexed accessors have a name ending by a singular. For example:
public Collection getElements() {...}
public IElement getElement(int i) {...}

  • NAME-16

Some method names are normalised according to the kind of action that they perform:

Action Prefix Example
Conversion to toString()
Creation create createElement()

Variables

  • NAME-17

The first letter of a variable name is normalised to represent its visibility.

Prefix Visibility
s Static member
m Non static member
v Local variable
p Method parameter

Using a prefix can seem to be tiresome. However, Eclipse can be configured to integrate these prefixes, to directly generate the code with them. Moreover, using a prefix corresponding to the visibility dramatically increase the maintainability and can avoid some bugs.

Pay attention that the prefix must not correspond to the variable type: 's' doesn't mean that it's a String.

  • NAME-18

A variable name, whatever its visibility, is composed of letters, potentially including numbers, and mandatory begins by a lower case letter.

  • NAME-19

The dollar character ($) is forbidden in the variable name.

  • NAME-20

The underscore character (_) is forbidden in the variable name, except for the static final constants.

  • NAME-21

The variable name of a single character must be avoided. They are only tolerated for the temporary variable, like the loop counters (i, j, k ...).

  • NAME-22

The boolean properties are named with an adjective describing them. The general terms must be avoided, like ok, etc. Moreover, a boolean property doesn't need to be prefixed by is: name a variable available instead of isAvailable.

  • NAME-23

The collection variables are named with a plural, and potentially postfixed with their collection general type (Array, List, Map).

  • NAME-24

It's forbidden to use the same name for a method and a variable inside a same Class.

  • NAME-25

The names of the constants (static final) are composed of one word or a group of words with an underscore (_) to separate them. The name is written using only upper case letters.

Presentation category

Order

  • PRES-01

The declarations in a Java file follow a specific order:

  Javadoc of the file
  Package declaration
  Imports list
  Javadoc of the Class
  Class declaration
  Constants declaration (static final)
  Class variables declaration (static)
  Instance variables declaration
  Constructor
  Methods
  Inner Classes
  • PRES-02

Imports are grouped from the second level of their name, and alphabetically ordered.

  • PRES-03

Constants and variables declarations are ordered by decreasing visibility (public, package, protected, private).

  • PRES-04

Constants and variables declarations of a same visibility follow a logical order, mainly by functionality and role.

  • PRES-05

Methods are logically grouped, mainly by functionality and role.

  • PRES-06

Without alter the behaviour, order the code instructions to ease the reading and the understanding.

  • PRES-07

When several modifiers are used in a declaration, they respect a specific order:

  public
  protected
  private
  abstract
  static
  final
  transient
  volatile 
  synchronized
  native
  strictfp

Length

  • PRES-08

A file must not contain more than 2000 lines.

  • PRES-09

A method or a constructor must not contain more than 50 lines.

  • PRES-10

A line must be longer than 120 characters.

Style

  • PRES-11

The indentation is done only with spaces, and an indentation unity corresponds to 4 spaces.

  • PRES-12

The code is formatted as the Java standard:

Opening braces '{' are located at the end of the code line and preceded by a space
Closing braces '}' are located on a new line with the same indentation level than line containing the corresponding opening brace. It can be followed only by a new line, or a space with an else, a catch or a finally.
  • PRES-13

The cases of a switch instruction are located at the same indentation level than the switch. However, their code block is indented with one more level.

  • PRES-14

All the control blocks (if, for, while, do, switch,...) must be surrounded by braces, even if it's an empty or a single line block.

  • PRES-15

Any useless or unnecessary braces are forbidden.

  • PRES-16

The declarations extends, implements and throws must be located on a separated line, indented as the body of the related Class or method.

  • PRES-17

If a method contain a lot of parameters, which doesn't fit on a single line, put only one parameter per line. Each line is indented as the body of the method.

  • PRES-18

When an instruction doesn't fit on a single line, it is advised to insert a line break after a comma, or after an operator.


Empty line, space and bracket

  • PRES-19

The use of empty lines must respect some recommendations:

A single empty line must be inserted:
Between a method declaration and its first instruction
Before a new block
Between logical section in the body of a method
Before a line of code comment
After a block of code linked to a comment, to understand easily the range of the comment
Between two methods
Two empty lines must be inserted:
Between the different sections of a source file (declaration section, properties section, methods section, etc.)
  • PRES-20

A space must be inserted before and after any binary operator (except the '.').

  • PRES-21

A space must be inserted before an opening brace.

  • PRES-22

A space must be inserted between any key word (if, while, for, etc.) and the bracket which follows it.

  • PRES-23

A space must be inserted after the commas, in a list of parameters.

  • PRES-24

A space must be inserted after each semi-colon in a for loop declaration.

  • PRES-25

A space must be inserted after a cast instruction.

  • PRES-26

A space must be NOT be inserted between two opening brackets, or two closing brackets.

  • PRES-27

A space must be NOT be inserted between the operators '++' or '--' and the affected variable.

  • PRES-28

A space must be NOT be inserted a method name and the opening bracket introducing its parameters.

  • PRES-29

Use brackets each time an expression can be confused, or to highlight the treatment order of the operators.
For example:

  // Avoid
  if (vNum1==vNum2 && vNum3==vNum4) {
      vTotal = vNum1 / vNum2 + vNum3 * vNum4;
  }

  // Prefer
  if ((vNum1==vNum2) && (vNum3==vNum4)) {
      vTotal = (vNum1 / vNum2) + (vNum3 * vNum4);
  }
  • PRES-30

A return instruction must NOT use brackets, except if it's a conditional expression.

Variable declaration

  • PRES-31

Declare only one variable per line.

  • PRES-32

Group the variable declaration at the beginning of a block of code, without altering the behaviour.

Tips and best practices

Useless code

  • TIPS-01

Delete unused imports.

  • TIPS-02

Delete any private property, local variable, parameter and private method not used.

  • TIPS-03

Do not use generic import (with '*').

  • TIPS-04

It's forbidden to import the packages sun.*

  • TIPS-05

A Java source file must contain one and only one public Class or Interface.

  • TIPS-06

All the Classes must be contained by a package. This means that it must always have a package declaration at the beginning of the source file.

  • TIPS-07

The use of inner Classes, Interfaces, and anonymous Classes must be limited to simple treatments.

  • TIPS-08

A Class with only private constructors must be declared as final.

  • TIPS-09

A Class with only static methods must not declare any public constructor.

  • TIPS-10

A default constructor must always be explicitly declared if it is needed.

  • TIPS-11

It's mandatory to call explicitly the inherited constructor when a constructor is overridden by a child Class, using the super key word.

  • TIPS-12

It's recommended to put only the instance property initialisation in a constructor, and put the treatments in dedicated methods called after the instance creation.

  • TIPS-13

An Interface is used to define a type, not to gather and share constants.

Methods

  • TIPS-14

The parameter declaration must not use concrete types. In case of exception, it must be argued and explained in the method comment.

  • TIPS-15

Always declare a method with the most restrictive visibility possible.
For a method, the more common visibilities are public and private. The private visibility must be preferred by default to the others. It is important to limit public and protected visibility to reduce the dependency points with others Classes, and improve the code flexibility.

  • TIPS-16

The methods and constructors must not have more than 5 parameters.

  • TIPS-17

The cyclomatic complexity of a method or constructor must not exceed 15, otherwise the method must be split. This metric indicates the number of conditional path (if, else, case, etc.) of a method and thus the theoretical number of unit tests needed to fully validate it. It's a good indication of the code maintainability.

  • TIPS-18

In a base Class, do not use abstract method. The undefined methods must be used in Interfaces or abstract Classes only.

  • TIPS-19

A Class must not contain a private method with the same signature (name and arguments) than a private method of its parent Class.

  • TIPS-20

If a Class redefines the clone method, it must always call the parent method with super.clone().

  • TIPS-21

If a Class redefines the finalise method, it must always call the parent method with super.finalize() as its last instruction.

  • TIPS-22

If a Class redefines the equals method, it must always do it with the same signature than the equals method of the Object Class.

  • TIPS-23

If a Class redefines the equals method, it must also redefine the hashCode method (and vice versa).

Variables

  • TIPS-24

Always use the most restrictive visibility to a property. The properties are generally private and may be read and written by accessors (get and set). The constants (final static) are an exception, as they can be declared public and accessed directly.

  • TIPS-25

All property and variable must be explicitly initialised at its declaration, even with the default value.

  • TIPS-26

All the method parameters must be declared as final and thus not modified in the method context. Any exception must be argued and explained in the method comment.

  • TIPS-27

An array declaration must be located on the variable type, and not on its name.

  • TIPS-28

A collection property must never be initialised as null.

  • TIPS-29

The getter accessors of a collection property must only return a copy of the collection, or an immutable collection, to preserve the encapsulation principle.

  • TIPS-30

When a method is overridden, the implicit contract of the super method must be preserved by its redefinition.
For example, the implicit contract of equals specifies that it is reflexive, symmetric, transitive, and consistent. When equals is called on an instance, the developer can't simply know if it has been overridden or not, and he expects that the implicit contract is respected.

Expressions

  • TIPS-31

Each line must contain a single instruction. Empty instructions and nested instructions are forbidden.

  • TIPS-32

The access to a static property or method must be done using the name of the Class which define it, never from an instance.

  • TIPS-33

A method must contain at most one return instruction.

  • TIPS-34

The cast and conversions must be done explicitly.

  • TIPS-35

When possible, use the arithmetic operators with affection (+=, -=, etc.).

  • TIPS-36

A for loop parameter must not be re-affected or modified inside the loop body.

  • TIPS-37

Do not use an affectation instruction inside a test or a control structure.

  • TIPS-38

In the comparison, the constants must be located on the left of the comparison operand.

  • TIPS-39

The ternary conditional operator (condition ? if true : if false) is only tolerated for simple case.

  • TIPS-40

Never use the '==' operator to compare two Strings, but call the equals method.

Control structures

  • TIPS-41

A switch instruction must always contain a default case.

  • TIPS-42

A switch case must always finish by a break, except to group cases with exactly the same behaviour. The default case must also finish by a break even if it's redundant.

  • TIPS-43

In a switch, try to put the more frequent case first.

  • TIPS-44

The number of nested control blocks level must not exceed 2.

  • TIPS-45

Do not use a while loop where a do while is appropriate.

  • TIPS-46

The for loop must be used for any loop corresponding to the progress of at least one variable according to a regular rule. Otherwise, the while loop is preferred.

  • TIPS-47

The continue and break instruction are forbidden in the iterative structure (do, while, for).

  • TIPS-48

The labels (goto) are strictly forbidden.

  • TIPS-49

When testing an enumeration, always consider the default case of a switch, or the else of an if to anticipate the creation of new values.

  • TIPS-50

In the declaration of a classic for loop, the indirect calls, like collection.getSize(), must be avoided.

  • TIPS-51

Whenever it's possible, use a foreach loop instead of a classic for loop.

Exceptions

  • TIPS-52

When possible, instead of using a return code, use custom exceptions.

  • TIPS-53

Do not use exception to quickly go from a code block to another, it's not a goto instruction.

  • TIPS-54

Create custom exceptions, which inherit from the standard exceptions java.lang.Exception and java.lang.RuntimeException. The standard exceptions are too general to be used directly, as they can't be easily distinguished.

  • TIPS-55

Remember to reuse the simple exceptions defined in the JDK.

  • TIPS-56

Functional exceptions must inherit from java.lang.Exception. Technical exceptions must inherit from java.lang.RuntimeException.

  • TIPS-57

If at a given level we don't know how to treat an exception, the best is to not catch it.

  • TIPS-58

When an exception is caught in a catch block, it must not be re-thrown, but encapsulated.

  • TIPS-59

When an exception is caught in a catch block, it must not be "digested" (with an empty catch block for example).

  • TIPS-60

Always catch the most precise exception: do not catch java.lang.Exception, java.lang.RuntimeException or java.lang.Throwable.

  • TIPS-61

Order the exception catch instruction from the most precise to the most general.

  • TIPS-62

In a throws clause, an exception must not be declared twice.

  • TIPS-63

In a throws clause, an exception which inherits from another one already declared must not be declared.

  • TIPS-64

In a throws clause, an exception which can't append must not be declared.

  • TIPS-65

An exception must be immutable, it means that all its properties must be declared as final.

  • TIPS-66

The resources release must be done in a finally block.

Performance

  • TIPS-67

Put outside of a loop any invariant or call of a method which is independent of the loop iteration.

  • TIPS-68

Foster the use of static, when possible.

  • TIPS-68

Foster the use of inlining, when relevant, by keeping the methods simple and short, declaring them final to ensure that they can't be overridden, and static.

  • TIPS-69

Use the synchronized keyword only when relevant.

  • TIPS-70

To concatenate and manipulate Strings, use a StringBuilder instance.

  • TIPS-71

Limit the use of MessageFormat to the access to a properties file, for internationalisation purpose.

  • TIPS-72

Limit the indexed access to an array content. If an array content is accessed several times, access it only once and store the value in a local variable if possible.

  • TIPS-73

Recursive algorithms must be avoid and replaced by iterative algorithms when it's possible.

General best practices

  • TIPS-74

Avoid the use of the "Double-checked locking" mechanism. For instance, this is the recommended way to design a singleton to avoid it:

public final class MySingleton {
    private static MySingleton sInstance = new MySingleton();

    public MySingleton getInstance() { 
        return sInstance;
    } 

    private MySingleton(){
    }
}
  • TIPS-75

To make comparison use the min and max values defined in the Classes of the package java.lang, which encapsulate the primitive numeric types.

  • TIPS-76

Do not use float and double for arithmetic calculation. These primitive types respect the IEEE 754 specification, which normalises the representation of numbers with floating comma. It's made to increase the calculation performance, but doesn't guarantee the result precision.

  • TIPS-77

Use the BigDecimal and BigInteger constructor, taking a String as parameter.

  • TIPS-78

The use of java.util.Vector, java.util.Hashtable and java.util.Enumeration are forbidden. If a thread-safe instance is needed, use java.util.List, java.util.HashMap and java.util.Iterator, with the methods Collections.synchronizedList() and Collections.synchronizedMap().

  • TIPS-79

To work on collections and arrays, use the utilitarian methods available in java.util.Collections and java.util.Arrays.

  • TIPS-80

To copy an array, use the method System.arraycopy().

  • TIPS-81

Avoid the use of System.out.println() and system.exit().

  • TIPS-82

To initialise complex static properties, use a static block.

  • TIPS-83

In a method signature, and in a variable declaration, it's recommended to use Interfaces and not concrete types.

  • TIPS-84

Encapsulate and centralise the management of the date, do not get the system date directly. This can be very useful during a test or validation phase.

  • TIPS-85

Do not create a new instance of the Class java.lang.Boolean, use the existing instances Boolean.TRUE and Boolean.FALSE.

  • TIPS-86

Do not use literals, as magic numbers or hard coded String, but use named constants. The only tolerated values are -1, 0 and 1, which can appear in control structures.

Comments category

  • COMM-01

The use of Javadoc comment is mandatory for the whole project scope, for all the visibility levels (not only the public elements) and for all the declarations types (Class, Interface, method, property, etc.).

  • COMM-02

If a Javadoc comment contain more than one line, the first one must contain only the opening tag /**. The following lines must begin by a star (*) and a space, and all the stars characters must be aligned. The last line must contain only the closing tag */, preceded by a space to align the stars.

  • COMM-03

The opening comment tags /** and // are always followed by a space.

  • COMM-04

The code comment must always be located at the current code indentation level.

  • COMM-05

A file Javadoc, located before the package declaration, is normalised and must respect the Eclipse standards:

    /*******************************************************************************
     * Copyright (c) ${date} ${company}.
     * All rights reserved. This program and the accompanying materials
     * are made available under the terms of the Eclipse Public License v1.0
     * which accompanies this distribution, and is available at
     * http://www.eclipse.org/legal/epl-v10.html
     * 
     * Contributors:
     *     ${contributor} (${company}) - initial API and implementation
     ******************************************************************************/
  • COMM-06

A Class Javadoc is normalised and must respect the following template:

    /**
     * First sentence describing the Class role and services.
     * 
     * Detailed description of the Class behaviour.
     *
     * @author  $Author$
     * @version $Revision$
     */
  • COMM-07

A method Javadoc is normalised and must respect the following template:

    /**
     * First sentence describing the method role.
     * 
     * Detailed description of the method behaviour and implicit contract.
     *
     * @param  pParameterName Parameter description
     * @return Return value description
     * @throws ExceptionType Description of the potential cause of exception
     */
  • COMM-08

A Javadoc comment always ends its description by a dot '.'. This is used during the documentation generation to structure the paragraph.

  • COMM-09

The description associated to a Javadoc tag (@param, @return, etc.) must not end by a dot '.'.

  • COMM-10

An empty line must be inserted in a Javadoc comment between the description paragraphs and the Javadoc tags.

  • COMM-11

The Javadoc tags must be used only when it's relevant.

  • COMM-12

A code is considered as enough documented when the comments correspond to 40% of the number of lines.

  • COMM-13

A code block must not be committed as comment, except in an explanation purpose.

  • COMM-14

A comment is mandatory in English, and must not contain any accented or special character, as a page break.

Architecture category

  • ARCH-01

The project corresponds to a product, thus the releases are delivered to the final user as a whole product, with independent P2 repositories for the optional features.

  • ARCH-02

All plug-ins must compile and run with Java 1.7 (Execution Environment = JavaSE-1.7).

  • ARCH-03

The build architecture is driven by Maven, thus the Java build folder is target/classes (and not bin/).

  • ARCH-04

A plugin or feature provider must be Polarsys

  • ARCH-05

A plugin or feature version must match the whole product version at each release. The component versions must be qualified, like 0.7.0-qualifier in the manifest, and 0.7.0-SNAPSHOT in the POM.

  • ARCH-06

A feature name must be: org.polarsys.esf.myfeature.

  • ARCH-07

A plugin id must be: org.polarsys.esf.parentfeature.myplugin.

  • ARCH-08

A plugin content must respect the following structure:

  org.polarsys.esf.feature.plugin
  |- src
  |- icons
  |- META-INF
  |- properties
  |  |- nls
  |- build.properties
  |- plugin.xml
  |- pom.xml
  • ARCH-09

The plugins dependencies must be as simple and clear as possible. To build a dependencies graph closed to a tree, this principles must be respected:

- If a plugin requires another plugin of the project, it must mandatory reexport it with visibility:=reexport.
- If a plugin requires an external plugin of the project, it must mandatory reexport it with visibility:=reexport.
- If a plugin requires another plugin of the project, it must reference the last release version, as minimal version.
- All dependencies must be explicitly declared, even if it's required only at runtime, with a required plugin (not an imported package) link.
  • ARCH-10

In a feature, the configuration Strings, from feature.xml, must be externalised in properties file named feature.properties, and located at the plugin root.

  • ARCH-11

In a plugin, the configuration Strings, from MANIFEST.MF and plugin.properties, must be externalised in properties file named plugin.properties, and located in the folder properties at the plugin root.

  • ARCH-12

The code Strings must be externalised in properties file named messages.properties, located in the folder properties/nls at the plugin root. If the externalisation is not relevant for a String, for example for debug Strings, it must be tagged using //NON-NLS-$.

  • ARCH-13

Each Eclipse plugin have an Activator explicitly declared, who manage the plugin lifecycle. The activator implementation is encapsulated in an EMFPlugin Class, and is a Singleton. Its concrete type depends of the plugin role, EclipseUIPlugin or EclipsePlugin, according to the fact that the plugin contribute to the UI or not.

  • ARCH-14

In a plugin context, the build.properties file describes the files that must be included at runtime. It must include these contents (when it exists):

  In 'Binary build' category:
    META-INF/
    about.html
    icons/, resources/, models/, etc. (All folders containing runtime resources)
    properties/
    plugin.xml
    schema/
        
  In 'Source build' category:
    about.html

Pay attention to NOT include the following files:

    .classpath
    .project
    src/
    target/
    build.properties
  • ARCH-15

In a feature context, the build.properties file describes the files that must be included at runtime. It must include these contents (when it exists):

  In 'Binary build' category:
    epl-v10.html
    feature.properties
    feature.xml
    licence.html
        
  In 'Source build' category:
    build.properties
    epl-v10.html
    licence.html

Back to the top