Our main aim is to have a clean code, avoid common silly mistakes and reduce the load on engineers during PR reviews. This is a team effort and If anyone has something that’s generally applicable, let’s talk and decide whether it should be baked into our style guide— so everyone can benefit from it
The bad code creates a lot of distractions. It causes developers to waste time and energy navigating through functions, classes, and files, and pouring over code trying to understand it.
Working on a project where developers care about clean code makes it easy to understand its virtues; the developer can read the code from top to bottom in one go and clearly understand what it does. It makes code manageable and maintainable in the long term, isolating changes and increasing the efficiency of the team.
However, each era will have different ideas and opinions, and different teams will also have different conventions. So best to take this as a rule of thumb, not to follow it strictly.
Also, try not to use too much OOP. Because Kotlin is a more functional-friendly type of programming language. And OOP doesn't do very well in Jetpack compose if we have a plan to migrate in the future
Everything in code hides a meaning behind its use; it has an intention and the developer must reflect this meaning using an appropriate name for it. Follow the Name Convention of the project. For more information click here.
- On the whole, naming should follow Java standards, as Kotlin is a JVM-compatible language.
- Good naming makes it easier to read and understand code.
- All naming has to be simple, clear and mnemonic (short and meaningful).
- Abbreviations and acronyms should use camel case as normal words (e.g., XmlHttpRequest, QrCodeReader, userId).
- Avoid fully short-form naming unless the name or context is widely known by others. But still please avoid it and write the full name as it gives more clarity of what the variable actually does.
- For example,
val ea = “” // Email Address
This can cause confusion as new people wouldn't know what isea
- Another example is
password
. Some people love writing it as short-formpwd
. But some people might prefer the full-namepassword
. - Also, most of the IDE now comes with auto-complete. It wouldn't hurt to type a few words more on your keyboard
- For example,
in general, comments are excuses for bad code. Feels the need to add a comment, which means that the developer probably needs to refactor the code. Add comments for very specific case methods; add a general comment which explains the main purpose for all interfaces and unique classes.
Upper CamelCase
is used for classes.
- The same applied to Sealed Classes
Classes names also come with the suffix which defines the type of the class
- BaseActivity
- BaseFragment
- BaseViewModel
- UserAPI
- Enum naming should be
ALL_CAPS
with an underscore separating words - Constants should be
ALL_CAPS
with an underscore separating words
Written in lowerCamelCase
- For requesting data from the server use
load***
prefix:load**Outlet
*,load**User
- For sending the data to the server user
send*
prefix*:send**Profile
, **send**Info
- For any click events, use
onXXXXXClicked
. For example,onLoginClicked
- Generally, written in
lowerCamelCase
. Single character values must be avoided, except for temporary looping variables. - We also prefer a single declaration per line.
- Boolean types start with
is
**prefix.is**ShowTitle
- Lists come with
**List
suffix.**news**List**
Package names are similar to Java: all lower-case, multiple words concatenated together, without hyphens or underscores
Only include visibility modifiers if you need something other than the default public.
Access level modifiers should be explicitly defined for classes, methods and member variables.
Private fields for Kotlin always start with underscore. For example, val _privateFieldName : Int
There should be exactly one blank line between methods to aid in visual clarity and organisation. Whitespace within methods should separate functionality, but having too many sections in a method often means you should refactor several methods.
Conditional statements are always required to be enclosed with braces, irrespective of the number of lines required.
Unlike switch statements in Java, when statements do not fall through. Separate cases using commas if they should be handled the same way. Always include the else case.
Constants are defined using the val
keyword, and variables with the var
keyword. Always use val
instead of var
if the value of the variable will not change.
Tip: A good technique is to define everything using val
and only change it to var
if the compiler complains!
- Unlike Java, direct access to fields in Kotlin is preferred.
- If custom getters and setters are required, they should be declared following Kotlin conventions rather than as separate methods.
- The Severity level of the Redundant semicolon has been set to ERROR via the Editor Inspections for All Changed Files and Warning for Everywhere else.
- This inspection will report redundant semicolon (;) tokens which are not required in Kotlin.
Avoid wild card imports ;)
- The Severity level of the Unused import directive has been set to ERROR via the Editor Inspections for All Changed Files and Warning for Everywhere else.
- This Inspection will report import statements in Kotlin code that are unused as error
- We should avoid applying the !! operator in our Kotlin code because there is a likelihood that the value will throw an exception if it is null.
- The Inspector will report any not-null assertion and provide a workaround.
- Other safer options include using null-safe calls (?) or the Elvis operator (?:).
- Spellchecker inspections help locate typos and misspellings in our code and fix them in one click
- This inspection is applied to code, literals and comments.
- Always run Optimize Imports and Reformat Code when working with changed XML files.
- The data element should always be placed top-most of the XML and the root view will follow.
- All properties that may be used within the layout should be defined and placed in the data element.
- Layout expressions should be kept small and simple, as they can't be unit tested and have limited IDE support. In order to simplify layout expressions, you can use custom binding adapters or a ViewModel.
- Hardcoded string usage is strongly discouraged, should use a @string resource. And if its for design purposes should use tools instead.
- Hardcoded colors are discouraged, should use the colors resource. if the color not exist please create one following the color naming conventions
- Hardcoded
dimens
and text sizes are strongly discouraged, should use thedimens
resource. - The corresponding layouts have to be named with the appropriate prefix: activity_login.xml, fragment_register.xml.
File names start with the type and finishes with a suffix which describes the purpose
- activity_home, fragment_home, viewstepitem
XML resource IDs have to use snake_case
.
IDs should be prefixed with the abbreviation of the element in the lowercase underscore.
- A TextView that displays a name → tv_name
- An EditText that inputs an email → et_name
- A Button that submits → bt_submit
Every string name starts with screen name as prefix
- **
complete_setup**_box_desc
, **login**_box_title
, **home**_top_section_rewards_label
Start with a prefix that describes the purpose of colour: **text**_fave
, **text**_pink
, **border**_black
Starts with the prefix menu: **menu**_home
, **menu_**settings
Starts with the prefix action*:* action**_data
; **action**_share
- icon: starts with the prefix ic: **
ic**_logo
, **ic**_share
, **ic**_login
- picture: starts with the prefix img:
i**mg**_description
- background: starts with the prefix bg: **
bg**_otp_active
- selectors: starts with the prefix selector: **
selector**_button_login
- screens: starts with the prefix screen: **
screen**_splash
ktlint
is an anti-bikeshedding linter with a built-in formatter for the Kotlin language.
ktlint
can reformat your code for you when there is an issue. This allows you to focus your time and energy on the more interesting problems of at hand.
Ktlint
provides two tools
- A linter to check for formatting errors
- A formatter to fix formatting errors
A perfect place to run this is in your local machine before you push your changes to a git repository.
Intergraiotn is done via a plugin ktlint-gradle. The Gradle plugin that automatically creates check and format tasks for project Kotlin sources, supports different Kotlin plugins and Gradle builds caching.
Add the ktlint
gradle plugin to your root-level build.gradle
file
buildscript {
...
repositories {
...
maven {
url "https://plugins.gradle.org/m2/"
}
}
dependencies {
...
classpath "org.jlleitschuh.gradle:ktlint-gradle:10.0.0"
}
}
Make sure the module contains .kt
files
To apply the ktlint
Gradle plugin in a module, add this plugin via the module Gradle file
id 'org.jlleitschuh.gradle.ktlint'
The module will be checked along with other modules once the ktlint
check is run.
This can also be added in all Projects Gradle files but is not recommended since our code base is Java and Kotlin.
To actually check your code’s formatting, run the following command from the command line:
./gradlew ktlintCheck
This will run through the project and report back any errors via the terminal which are found using the ktlint
set configuration.
The ktlint
check can also be run on a specific module that has been configured with ktlint
. To run a check on a specific module run the following command from the command line:
./gradlew :{some_module}:ktlintCheck
To automatically fix any errors which are reported by ktlintCheck
, you can run the following command from the command line:
./gradlew ktlintFormat
There could be some errors that can't be fixed automatically by this command line e.g usage of wildcards imports, for this you should manually resolve these.
Once everything is correctly formatted by running ktlinkFormat
or manually formatting, re-run ktlintCheck
Terminal should report Build as successful.
https://gist.github.com/wojteklu/73c6914cc446146b8b533c0988cf8d29