Skip to content

Kotlin code style

Alexander Yevsyukov edited this page Oct 21, 2023 · 10 revisions

Kotlin code of Spine SDK follows the standard conventions with the extensions and modifications described below.

Property names

For constants

Kotlin conventions for property names encourage using SCREAMING_SNAKE_CASE for constant properties.

Unlike in Kotlin conventions, we prefer lowerCamelCase for naming such properties for the following reasons.

1. Better readability

Compare "$group:$infix-fat-cli:$version" and "$GROUP:$INFIX-fat-cli:$VERSION".

Uppercase constants usually attract more attention than real interesting text around them. There's no need to SCREAM about them ALL_THE_TIME.

2. Flexibility to changes

This is more important than №1 above.

Suppose you have a dependency defined via constant that end up with interpolated string such as "$GROUP:$INFIX-fat-cli:$VERSION". The dependency is used in several modules of your project.

After some time, you figure out that the version to be used depends on some condition. So VERSION is no longer a const val but simply val. So, by standard convention, you now need to rename it. In turn, the constant which previously defined the dependency is also no longer a constant because its value is interpolated from non-constant. Now this property also has to be renamed. A slight extension of logic resulted in a cascade of changes.

If we do not SCREAM about constants, we hide the implementation details (at this micro level), making our code is less "fragile".

3. Consistency

Consider this code:

public object ProtoData {
    private const val VERSION: String = "1.0.1"
    public const val GROUP: String = "io.spine.protodata"
    internal const val INFIX: String = "protodata"
    //...
    public const val COORDINATES: String = "$GROUP:$INFIX-cli:$VERSION"
}

public data class ProtocPluginArtifact {
    private const val VERSION: String = "1.0.2"
    public val coordinates: String = "${ProtoData.GROUP}:${ProtoData.INFIX}-protoc:$VERSION:exe@jar"
}

The ProtoData.COORDINATES property is a constant, while ProtocPluginArtifact.coordinates is not because. It could not be declared as const val because interpolated from constant (!) properties of another object, ProtoData.

In order to reduce the mental load on remembering if a property is a real constant or not, we relaxed the constant value name rule.

It is still make sense to follow the SCREAMING_CASE rule for cases related to performance optimization.

For dependency objects

Instead of Gradle version catalogs we declare dependencies as Kotlin objects.

See the io.spine.internal.dependency package under buildSrc of a Spine SDK subproject for details.

Versions and Maven coordinates of dependencies are defined using lowerCamelCase.

Clone this wiki locally