-
Notifications
You must be signed in to change notification settings - Fork 0
Kotlin code style
Kotlin code of Spine SDK follows the standard conventions with the extensions and modifications described below.
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.
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.
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".
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.
Instead of Gradle version catalogs we declare dependencies as Kotlin objects.
See the
io.spine.internal.dependencypackage underbuildSrcof a Spine SDK subproject for details.
Versions and Maven coordinates of dependencies are defined using lowerCamelCase.