Вы уверены, что эти вычисления вашу программу нагружают? Просто проблема в том, что тут с какой стороны не подойти, она значительно усложнится от добавления таких вот оптимизаций. Если нужно поработать с каким-то значением много раз, то самое простое решение это сохранить его в локальную переменную там, где это необходимо. Другим простым решением может быть data class с неизменяемыми свойствами, и вместо изменений значений создание копии через copy. Тут ещё стоит спросить, а многопоточная ли у вас программа, а отображаются ли эти свойства где-то в UI.
Если же вопрос чисто академический, типа как в теории можно делать именно то, что вы хотите, то смотрите в сторону мемоизации или свойств-делегатов. Через мемоизацию функция от аргумента в результат при одинаковых аргументах будет высчитываться только один раз, результат обычно сохраняют в мапу. Тогда можно написать этих мемоизированных функций по количеству свойств класса, которые вы хотите кэшировать, и при обращении к проперти вызывать соответствующую функцию в gettere. Проблема тут в том, что в мапа это отображение из одного объекта в другой, а у функции несколько аргументов может быть. Придется писать data classы для каждого такого случая. На делегатах можно нагородить что-то такое
Шок контент, не рекомендую использовать
data class Box(var height: Int, var width: Int) {
val area by DependingCalculation(::height, ::width) {
println("Calculated")
height * width
}
}
class DependingCalculation<R>(private val dependencies: List<KProperty0<*>>, private val calculation: () -> R) {
private var prevValues = dependencies.map { it.get() }
private var cache = calculation()
operator fun getValue(thisRef: Any?, property: KProperty<*>): R {
val newValues = dependencies.map { it.get() }
return if (newValues == prevValues) {
cache
} else {
calculation().also {
prevValues = newValues
cache = it
}
}
}
constructor(vararg dependencies: KProperty0<*>, calculation: () -> R) : this(dependencies.asList(), calculation)
}
fun main() {
val box = Box(1, 2)
println(box.area)
println(box.area)
box.width = 4
println(box.area)
}