mirror of
https://github.com/home-assistant/developers.home-assistant.git
synced 2025-07-27 11:16:28 +00:00
Add documentation about constants
This commit is contained in:
parent
7c85921b92
commit
7c067a3cad
@ -74,3 +74,121 @@ TODOs in code tend to be forgotten over time. When someone read them later, they
|
|||||||
```bash
|
```bash
|
||||||
// TODO Missing feature (linked issue #404)
|
// TODO Missing feature (linked issue #404)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Constants
|
||||||
|
|
||||||
|
### Naming conventions
|
||||||
|
|
||||||
|
We follow the [Kotlin property naming guidelines](https://kotlinlang.org/docs/coding-conventions.html#property-names).
|
||||||
|
|
||||||
|
### Avoid magic numbers and strings
|
||||||
|
|
||||||
|
Magic numbers or strings in code can make it difficult to understand the purpose of a value, leading to poor maintainability. Always replace magic numbers or strings with named constants.
|
||||||
|
|
||||||
|
#### ❌ Don't do this
|
||||||
|
|
||||||
|
```kotlin
|
||||||
|
if (value == 42) {
|
||||||
|
// Do something
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
In this example, it’s unclear why the value 42 is being used. At the very least, you should add a comment explaining its purpose. Even better for future evolutions, it should be defined as a constant.
|
||||||
|
|
||||||
|
#### ✅ Do this
|
||||||
|
|
||||||
|
```kotlin
|
||||||
|
// Explanation or link about why we picked 42
|
||||||
|
const val SUPER_IMPORTANT_THRESHOLD = 42
|
||||||
|
|
||||||
|
if (value == SUPER_IMPORTANT_THRESHOLD) {
|
||||||
|
// Do something
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Organizing constants
|
||||||
|
|
||||||
|
General rule is if the constant is exposed outside of the file it needs to be properly be identifiable when imported either by its name or by its parents name.
|
||||||
|
|
||||||
|
#### Within a dedicated file
|
||||||
|
|
||||||
|
If you need to group related constants together, create an `object` to namespace them. Place the constants in a file suffixed with `*Constants.kt`. This approach improves organization and avoids cluttering unrelated files.
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
|
||||||
|
```kotlin
|
||||||
|
// filepath: NetworkConstants.kt
|
||||||
|
package package io.homeassistant.companion.android.network
|
||||||
|
|
||||||
|
object NetworkConstants {
|
||||||
|
val TIMEOUT = 30.seconds
|
||||||
|
const val BASE_URL = "https://api.example.com"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
OR
|
||||||
|
|
||||||
|
```kotlin
|
||||||
|
// filepath: NetworkConstants.kt
|
||||||
|
package package io.homeassistant.companion.android.network
|
||||||
|
|
||||||
|
val NETWORK_TIMEOUT = 30.seconds
|
||||||
|
const val BASE_URL = "https://api.example.com"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Alongside a class
|
||||||
|
|
||||||
|
For constants that are tightly coupled to a specific class, you can define them within the same file. Avoid using companion object unless absolutely necessary. Instead, place private constants outside the class definition at the top level. This reduces boilerplate and keeps the class focused.
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
|
||||||
|
```kotlin
|
||||||
|
// filepath: UserRepository.kt
|
||||||
|
package package io.homeassistant.companion.android.user
|
||||||
|
|
||||||
|
private const val DEFAULT_USER_ID = "guest"
|
||||||
|
|
||||||
|
class UserRepository {
|
||||||
|
fun getUserById(userId: String = DEFAULT_USER_ID): User {
|
||||||
|
// Implementation here
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
:::note
|
||||||
|
If you need the constant in test to avoid leaking it to the rest of the production code you can use the `VisibleForTesting` annotation.
|
||||||
|
|
||||||
|
```kotlin
|
||||||
|
@VisibleForTesting
|
||||||
|
const val DEFAULT_USER_ID = "guest"
|
||||||
|
```
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
|
#### Using companion objects
|
||||||
|
|
||||||
|
Use companion object only when constants or utility functions need to be exposed externally. This provides a clear namespace and avoids naming collisions.
|
||||||
|
|
||||||
|
When to use companion objects:
|
||||||
|
|
||||||
|
- **Namespacing for external use**: When constants or utility functions must be accessed externally (e.g., public or internal).
|
||||||
|
- **Intentional naming conflicts**: When multiple classes or entities in the same file share the same name for conceptually similar constants (e.g., EMPTY, DEFAULT).
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
|
||||||
|
```kotlin
|
||||||
|
// filepath: ApiClient.kt
|
||||||
|
package package io.homeassistant.companion.android.network
|
||||||
|
|
||||||
|
class RestApiClient {
|
||||||
|
companion object {
|
||||||
|
val DEFAULT_TIMEOUT = 60.seconds
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class WSClient {
|
||||||
|
companion object {
|
||||||
|
val DEFAULT_TIMEOUT = 10.seconds
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
Loading…
x
Reference in New Issue
Block a user