This following outlines the coding conventions and guidelines for spin development.
The
spincode-base may not yet be entirely compliant to these guidelines. Developers should thus make an effort to bring non-compliant code inline with these guidelines, especially when significant divergence is discovered.All new code should follow these guidelines.
-
Code should be formatted according to the Google Java Coding Style.
-
Checkstyle is used to enforce basic style compliance, however it can't do everything. Hence this guide.
spin is strictly versioned using Semantic Versioning. Importantly, we're not concerned with
increasing major version numbers when necessary to move things forward.
spin is developed in Java using Functional Style.
The following article is a great introduction to this style of development, specifically using Java.
In a nutshell, the style means:
-
Prefer immutability. Where possible make all state immutable. Where this is not possible, use the Builder Pattern pattern to capture mutable state, after which building produces immutable objects.
-
Never use
null. Variables (member, method, parameters) must never accept or storenullvalues. The only exception being when this is impossible when integrating with 3rd-party libraries. -
Use
Streams. Avoid use ofArrays,Collections,Iterators and/orIterables, especially in interfaces and method signatures. -
Never define
staticstateful global variables, unless they are constants. -
Use Dependency Injection to construct Objects, and avoid using
newwhere possible. -
Avoid using
gettersto obtain state from other objects when it can or should be injected. -
Never define or use global static singletons.
- Package Names should always be singular and not plural.
- Interface names must not be prefixed with an
I.
For example: An interface for a Truck should not be called ITruck, but instead Truck.
- Class names must not be post-fixed with
ImplorDAOetc.
For example: A class implementing the Truck interface should not be called TruckImpl.
- Classes that are the only implementation of an interface should be prefixed with
Defaultas they represent the default implementation.
For example: A class implementing the Truck interface should not be called DefaultTruck.
- Abstract classes must be prefixed with
Abstract, simply to indicate that one should not cast to them.
For example: An abstract class implementing the Truck interface should be called AbstractTruck.
- Method names for methods that return immutable properties, for which there is no setter method on the defining class, are not required to prefix the method name with get. There is no requirement to use Java Bean-style method naming conventions for immutable property getters.
For example: The method name for an immutable "age" property on the class should be called
age() and not getAge.
- Method names for methods with mutable values *must adopt Java Bean-style method naming conventions, and
thus define both
setandgetmethods.
For example: The method names for a mutable "age" property on the class should simply be called
getAge() and setAge(...).
- Methods that return
Optional,Exceptional,Stream,Streamable,Iterator,Iterableor any other immutable collection, should avoid using prefixing method names withget. There is no requirement to use Java Bean-style method naming conventions for such methods.
For example: A method that returns a Stream of Addresses, should have the signature
Stream<Address> addresses() and not Stream<Address> getAddresses().
-
Where possible, make constructors
privateor packageprotected. This is to ensure that thenewoperator is only available for internal implementation use. -
To support
publicconstruction of classes, theBuilderpattern and/orpublic staticcreation helper methods should be adopted.
This pattern allows:
- Constructors to be refactored without breaking the public API of classes.
- Caching of immutable object-creation requests.
Class declarations should be organized in the following order:
publicstaticfinalconstantsprivatestaticfinalconstantsprivatefinalmembersprivatemembers- default constructor
- constructors
- methods (non-interface)
- overridden methods
staticmethodsstatictypes
- The use of
nullshould be avoided at all times! This is to preventNullPointerExceptions being produced. - This includes accepting or requiring them as input parameters, and returning them from methods.
- Thus, there's no requirement for
@Nullableor@NotNullable-style annotations appearing in interfaces or implementations.
spincontains zero logging. It does not use any logging framework, including that of the Java Platform.- To provide information and feedback to users and developers,
spininstead uses a Telemetry Framework, that allows clean integration with Integrated Development Environments (IDEs) and Commandline Tooling, which themselves define how the logging of Telemetry occurs.
- Dependency Injection is used extensively in the
spincode base. It should be used where ever possible