Coding Conventions
Below you find some high level design principles. With respect to the low-level code style, see the checkstyle file.
Design Principles
Implementation against Interfaces
The library is developed to allow users to focus on its interfaces. Code should implement against an interface (e.g., the left hand side of an assignment should be an interface).
Naming, Code is Documentation
Class names, member names and variable names are as descriptive as possible (feasible). Names are formed using camel notation from the general to the special property. Implementation details are appended. Examples:
periodStart
periodEnd
RandomVariableFromDoubleArray
DiscountCurveInterpolation
A reassignment of a reference that alters the meaning should be avoided. A temporary assignment with a different meaning should be avoided. Example:
Wrong:
var discountFactor = (1 + forwardRate * periodLength);
discountFactor = 1.0/discountFactor;
Correct:
var forwardBond = (1 + forwardRate * periodLength);
var discountFactor = 1.0/forwardBond;
Naming of Interfaces
Interfaces should come with names describing the core concept (like BrownianMotion
or RandomVariable
or Curve
).
Implementations pick up the name of the main interface followed by a specification of an implementation aspect (
like RandomVariableFromDoubleArray
).
Naming of Collections
Collections are named as the plural of their items. Example:
Period period = periods.get(periodIndex);
In cases where it adds clarity the collection type can be used as a suffix instead of the plural. Example:
RandomVariable sensitivity = sensitivityMap.get(riskFactor);
Naming of Arguments
If constructor arguments or setter (builder) arguments are used to set fields, the field and the argument have the same name, i.e., we use
private final double value;
Skalar(double value) {
this.value = value;
}
Naming of Unit Tests
Unit test names are end with the word Test
and formed as XxxYyyTest where Xxx is the name of the primary class being
under test (it may be that a tests is testing a broader aspect of the class) and Yyy optionally specifies an aspect.
Example: LIBORMarketModelCalibrationTest
. The methods of the unit test start with the word test
.
Thread Safety
The library is developed with thread safety in mind.
- Classes prefer a design resulting in effectively immutable object.
- Method calls are idempotent.
- Method calls are free of side effects.
- Members are final whenever possible.
Lazy Initialization
The library utilized lazy initialization for time consuming task. Object construction is expected to require minimal resources.
Serialization
The library is developed with object serialization in mind.
- Classes should implement the
Serializable
interface.
Language
Language Extensions
The code is written in Java. That is, it avoids language extensions like Lombok.
Java Modules
The library will export Java 9 modules.
Language
Language Extensions
The code is written in Java. That is, it avoids language extensions like Lombok.
Java Modules
Starting with version 5.x the library will export Java 9 modules.
Other Principles
- Code in
src/main
should conform to DRY (don't repeat yourself). Unit tests insrc/test
should be self-contained and code duplication (e.g. create a model for a specific purpose) is fine.
Documentation
JavaDoc with MathJax
Every public interface, class, method, enum comes with a complete JavaDoc. If there are mathematical formulas, we use MathJax. (MathJax is available due to a configuration in the Maven pom.xml).
Code Style
We follow loosely the Eclipse coding conventions, which are a minimal modification of the original Java coding conventions. See https://wiki.eclipse.org/Coding_Conventions
See also the Spring coding conventions, see https://github.com/spring-projects/spring-framework/wiki/Code-Style
We repeat some of the aspects:
-
Indentation uses a single TAB character (as for the Spring coding convention and the Eclipse coding convention).
-
Files are UTF-8 encoded with Unit line endings.
-
Lines do not have trailing whiltespaces.
We deviate in some places:
-
We allow for long code lines. Some coding conventions limit the length of a line to something like 80 characters (like FORTRAN did in the 70'ies). Given widescreen monitors we believe that line wrapping makes code much harder to read than code with long(er) lines.
-
We usually do not make a space after statements like
íf
,for
. We interpretíf
andfor
as functions and for functions and methods we do not have a space between the name and the argument list either. That is, we write
if(condition) {
// code
}
The project is using a checkstyle profile, which currently only a very limited set of style issues. See finmath-checkstyle.xml .