Состояние object в Kotlin
У object могут быть и var, и
val. Изменяемые поля живут столько же,
сколько живёт сам singleton - пока работает
приложение или пока загружен модуль. Это одно
общее состояние на программу: оно лежит
в object, а не в полях отдельных
экземпляров класса:
object RateLimit {
private var hits = 0
val maxHits = 5
fun tryHit(): Boolean {
if (hits >= maxHits) return false
hits += 1
return true
}
fun remaining(): Int = maxHits - hits
}
fun main() {
repeat(6) { RateLimit.tryHit() }
println(RateLimit.remaining())
}
Ключевое слово private у поля или функции скрывает
деталь внутри object. Снаружи остаются
только нужные команды - так проще не испортить
счётчик прямой записью в переменную.
Простой in-memory кэш тоже часто оформляют как
object с картой или списком:
object UserCache {
private val store = mutableMapOf<String, String>()
fun put(id: String, name: String) {
store[id] = name
}
fun get(id: String): String? = store[id]
}
fun main() {
UserCache.put("1", "Ann")
println(UserCache.get("1"))
println(UserCache.get("2"))
}
Общее состояние удобно, но его нужно осознанно
ограничивать: один object с открытыми
var на весь проект усложняет отладку.
Скрывайте данные и давайте узкий API через
методы - тот же принцип, что и у приватных
полей класса.
Сделайте object TodoStore с приватным
mutableListOf<String>(), методами
add(title: String) и
size(): Int. Добавьте две строки и
выведите размер.
Сделайте object LastError с
var message: String? = null и функцией
clear(). Запишите "timeout",
выведите, вызовите clear(), снова
выведите message.