Development Guidelines

The following guidelines are used for Orekit development.

Development

Orekit is a low level library. It may be used in very different contexts which cannot be foreseen, from quick studies up to critical operations. The main driving goals are the following ones:

  • validation

  • robustness

  • maintainability

  • efficiency

The first goal, validation, implies tests must be as extensive as possible. They should include realistic operational cases but also contingency cases. The jacoco tool must be used to monitor test coverage. A very high level of coverage is desired. We do not set up mandatory objective figures, but only guidelines here. However,a 60% line coverage would clearly not be acceptable at all and 80% would be considered deceptive.

The second goal, robustness, has some specific implications for a low level component like Orekit. In some sense, it can be considered an extension of the previous goal as it can also be improved by testing. It can also be improved by automatic checking tools that analyze either source code or binary code. The findbugs tool is already configured for automatic checks of the library using a maven plugin.

This is however not sufficient. A library is intended to be used by applications unknown to the library development team. The library development should be as flexible as possible to be merged into an environment with specific constraints. For example, perhaps an application should run 24/7 during months or years, so caching all results to improve efficiency may prove disastrous in such a use case, or it should be embedded in a server application, so printing to standard output should never be done. Experience has shown that developing libraries is more difficult than developing high level applications where most of the constraints are known beforehand.

The third goal, maintainability, implies code must be readable, clear and well documented. Part of this goal is enforced by the stylistic rules explained in the next section, but this is only for the automatic and simple checks. It is important to keep a clean and extensible design. Achieving simplicity is really hard, so this goal should not be taken too lightly. Good designs are a matter of balance between two few objects that do too many things internally an ignore each other and too many objects that do nothing alone and always need a bunch of other objects to work. Always think in terms of balance, and check what happens if you remove something from the design. Quite often, removing something improves the design and should be done.

The fourth goal, efficiency, should be handled with care to not conflict with the second and third goals (robustness and maintainability). Efficiency is necessary but trying too much too achieve it can lead to overly complex unmaintainable code, to too specific fragile code, and unfortunately too often without any gain after all because of premature optimization and unfounded second-guess.

One surprising trick, that at first sight might seem strange and inappropriate has been used in many part for Orekit and should be considered a core guideline. It is the use of immutable objects. This trick improves efficiency because many costly copying operation are avoided, even unneeded one added for defensive programming. It improves maintainability because both the classes themselves and the classes that use them are much simpler. It also improves robustness because many (really many …) difficult to catch bugs are caused by mutable objects that are changed in some deeply buried code and have an impact on user code that forgot to perform a defensive copy. Orbits, dates, vectors, and rotations are all immutable objects.

Style Rules

For reading ease and consistency, the existing code style should be preserved for all new developments. The rules are common ones, inherited mainly from the Sun Code Conventions for the Java Programming Language guide style and from the default checkstyle tool configuration. A few of these rules are displayed below. The complete definition is given by the checkstyle configuration file in the project root directory.

  • header rule

all source files start with the Apache license header,

  • indentation rules

no tabs, 4 spaces indentation, no indentation for case statements,

  • operators wrapping rules

lines are wrapped after operators (unlike Sun),

  • whitespace rules

operators are surrounded by spaces, method parameters open parenthesis is not preceded by space, lines do not end with white space,

  • curly brace rules

open curly brace are at end of line, with the matching closing curly brace aligned with the start of the corresponding keyword (if, for, while, case or do),

  • encoding rules

characters encoding is UTF8, the git property core.autocrlf should be set to input on Linux development machines and to true on Windows development machines (to ensure proper conversion on all operating systems),

  • naming rules

classes names begin with upper case, instance methods and fields names begin with lower case, class fields are all upper case with words separated by underscores,

  • ordering rules

class variables come first, followed by instance variables, followed by constructors, and followed by methods, public modifiers come first, followed by protected modifiers followed by private modifiers,

  • javadoc rules

all elements have complete javadoc, even private fields and methods (there are some rare exceptions, in case of code translated from the fortran language and models with huge parameters sets),

  • robustness rules

switch/case construct have a default argument, even when all possible cases are already handled, as many classes as possible are immutable,

  • miscellaneous rules

star imports are forbidden, parameters and local variables are final wherever possible.

Design Rules

  • coverage (validation)

seek for a line test coverage of at least 80% (more is better)

  • findbugs (robustness)

fix all errors and warnings found by findbugs

  • no runtime assumptions (robustness)

do not make assumptions on the runtime environment of applications using Orekit (they may be embedded with no console, no possible user interaction, no network, no writable file system, no stoppable main program, have memory constraints, time constraints, be run in different linguistic contexts …)

  • simplicity (maintainability)

follow Occam’s razor principle or its declination in computer science: KISS (Keep It Simple, Stupid)

  • balanced design (efficiency)

seek efficiency, but do not overstep robustness and maintainability

  • immutable objects (robustness, maintainability)

use immutable objects as much as possible

  • checkstyle (style)

fix all errors and warnings found by checkstyle