You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/android/best_practices.md
+54-5Lines changed: 54 additions & 5 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -38,7 +38,9 @@ Logging is essential but should be used judiciously. As Jake Wharton says in his
38
38
39
39
When working with time, date, or duration, avoid using primitive types. Instead, use strong types to prevent unit mix-ups.
40
40
41
-
### ❌ Don't do this
41
+
:::note[Example]
42
+
43
+
#### ❌ Don't do this
42
44
43
45
```kotlin
44
46
constvalTHRESHOLD=600000
@@ -52,7 +54,7 @@ fun main() {
52
54
}
53
55
```
54
56
55
-
### ✅ Do this
57
+
####✅ Do this
56
58
57
59
```kotlin
58
60
valTHRESHOLD=Instant.ofEpochSecond(60)
@@ -66,6 +68,8 @@ fun main() {
66
68
}
67
69
```
68
70
71
+
:::
72
+
69
73
:::warning
70
74
If you must use primitive types, ensure the variable name includes the unit (e.g., `THRESHOLD_MS` instead of `THRESHOLD`) to reduce ambiguity.
71
75
:::
@@ -113,10 +117,55 @@ Naming is hard, but smaller functions make it easier to choose meaningful names.
113
117
114
118
For more details, see [submit](/docs/android/submit).
115
119
116
-
## Additional notes
120
+
## Dependency injection (DI)
121
+
122
+
We use Dependency injection (DI) to help write modular, testable, and maintainable code. By using DI, we can decouple the classes from their dependencies, making it easier to swap implementations, write unit tests, and manage complex object graphs. DI also improves code readability and helps enforce the single responsibility principle.
123
+
124
+
### Use explicit qualifier annotations over `@Named`
125
+
126
+
When you need to inject multiple implementations of the same type (or primitive types), you must use a qualifier to distinguish between them. While the `@Named` annotation is a common approach, it relies on string identifiers, which can be error-prone and harder to refactor. Using custom qualifier annotations instead of `@Named` offers several advantages:
127
+
128
+
-**Discoverability**: Custom qualifiers make it easier to find where a specific dependency is used in the codebase.
129
+
-**Refactorability**: Renaming a custom annotation is straightforward and safe, while changing a string identifier requires searching for all string usages.
130
+
-**Type safety**: Custom annotations are checked at compile time, reducing the risk of typos or mismatches that can occur with strings.
131
+
-**Clarity**: Custom qualifiers make the code more self-explanatory and easier to understand.
* Qualifier for the [KeyChainRepository] used to select the key chain.
160
+
*/
161
+
@Qualifier
162
+
@Retention(AnnotationRetention.RUNTIME)
163
+
annotationclassNamedKeyChain
164
+
```
165
+
166
+
:::
117
167
118
-
-**Testing**: Write [unit tests](/docs/android/testing/unit_testing) for critical functionality to ensure reliability.
119
-
-**Code reviews**: Always review code for adherence to these best practices.
168
+
For a real-world example of migrating from `@Named("keyChainRepository")` to `@NamedKeyChain`, see [this pull request](https://github.com/home-assistant/android/pull/5667).
0 commit comments