Coding Conventions
overview
This document will take as the living document of the coding conventions and the best practices that we will follow through out the development lifeycle.
Naming
Package
- Package names should be lowercamelcase, multiple words concatenated together and without hypens or underscores
Methods
- written in lowerCamelCase, for example setValue
- always starting a verb indicating its intent getFoo, setBar, changeFoo
- Method orders should go in override first, visibility second(public, private) in alphabetic order
- Explicitly delcare return types at all times, within the exception when the body is a single line and single expression
Fields
- All fields should be written in lowerCamelCase.
- Static constant fields should be written in UPPER_CASE
- Do not prefix member variables with m like in java
- Do not prefix const vals with s
- Each variable should get its own declaration line
- Single character values to be avoided except the temporary looping variables
- Acronyms should be treated as words ie URL should be Url
- Non obvious variable types should be declared
Brace Style
- Use braces even for oneliner if else statements
Visibily modifiers
- Only include visibility modifiers if you need anything other than public
- Always make good use of the internal modifier. If you use internal modifier means this is used only inside the module which is great for hiding implementations
Prefer Data classes
- Prefer data classes for simple data handling objects
- If you are using data classes for API responses, make sure yo include @SerializedName annotations otherwise the build will break in release builds
- Data classes should be simple as possible. They should contain only the properties added in the constructor
- If you need additional logic to be added based on some properties in data classes, then create an extension property or an extension function
Custom extension functions and properties
- Extension functions are a great way to add functionality to a data class without converting it into a regular class. They can also be used to add a functionality to a class which you do not own or cannot modify
- When using extenstion functions, the function should either extend a specific narrow scoped class for a specific purpose or it should extend a common broadly scoped class for a generic purpose
Semi Colons
- Semi colons should be avoided whereever possible
Getters and setters
- Unlike in java, direct access to fields in Kotlin it is prefered via properties
- Be sure that any property you add that has the appropriate access modifier for the setter
Early returns
- Always rcreate local variables against Optionals & early return
BAD
fooBar?.let{
print("$it")
}
GOOD
val someItem = fooBar ?: return
print("$someItem")
Method Formatting
- If the function signature doesn't fit on a single line, use multiline syntax
- Use named paramaters always
Using Loops
- Prefer using higher order functions like filter and map to loops
Scope functions
- Make good use of let, run, with, apply and also.
#Whitespacing
- Never put a space after (, [, or before ], ).
- Always put a space after :
If Statemets
- We should always prefer to test for the positive condition in if statements rather than the negative condition
Other
- Avoid using :isInitialized using this means we have not setup our variables properly when they are referenced, which is a code smell. Your code should structure differently to avoid needing to check this property
Coding conventions General Guidelines apart from the above specific things
- If there is anything which is mentioned in this document, please follow from https://kotlinlang.org/docs/reference/coding-conventions.html
- It is important to follow the general coding conventions for most things as this makes it easier for new developers to understand our code, but there are times when your particular problem can be solved in a non standard way that is actually more readable in that particular case.
Safe variable declaration
- Always use a non-nullable type whenever possible
- Always declare variables as val unless you have a specific reason to use var
- Also use immutable collections instead of mutable ones
- If you need to declare a variable before assigning it a value instead of nullable declare it as lateinit
- If you find yourself doing this check if you should instead refactor your code to a lambda declaration to initialize the value instead
e.g. val x = { when (y) { … } }
- Use safe calls and elvis operator with nullable variables https://kotlinlang.org/docs/reference/null-safety.html#safe-calls https://kotlinlang.org/docs/reference/null-safety.html#elvis-operator
- Do not use !! to force null pointer exceptions
Use When
https://kotlinlang.org/docs/reference/control-flow.html#when-expression
-
In Java you mainly used the switch statement together with enums. In Kotlin switch has been replaced by when which can and should be used for a far wider array of flow management.
-
If you have a code block that has more than one if-statement you should almost always refactor it into a when.
-
If you have an if structure with only boolean checks sometimes it can be more readable with the if structures, so use common sense
Chaining Collections
- Whenever you are chaining multiple functions on a collection with more than trivial number of items, the best practise is to declare it as a sequence https://blog.kotlin-academy.com/effective-kotlin-use-sequence-for-bigger-collections-with-more-than-one-processing-step-649a15bb4bf
Tips
Strings
- Familiarise yourself with Kotlin String template https://kotlinlang.org/docs/reference/basic-types.html#string-templates
- Triple quoted Strings, i.e. ”"”some string”"”, are treated as literal and retain all formatting characters and require no escape characters
Operator overloading
- In Kotlin operators such as +, - and * are linked linked to corresponding functions and by providing those functions in your classes you can create some powerfully concise handling syntax in a DSL https://kotlinlang.org/docs/reference/operator-overloading.html https://kotlinlang.org/docs/reference/type-safe-builders.html
- Do not abuse this functionality, + sign already means something and regular code so using it for something else is misleading. Only do this inside your specific DSL!
Equality
The == operator in Kotlin is actually also overloaded (see above) and calls .equals(). If you need to check for reference equality the operator is ===