Необходимость непосредственного изменения глубоко вложенного объекта является признаком фундаментальной проблемы проектирования (отсутствие инкапсуляции). За исключением, может быть, если ваш объектный граф является моделью некоторой неумной структуры данных, такой как JSON или XML.
По крайней мере, вы должны разбить все создание внешнего объекта. У каждого объекта в дереве может быть функция, обеспечивающая получение некоторого возвращаемого значения, например:
class ObjectA {
var objectB: ObjectB? = null
fun requireObjectB() = objectB ?: ObjectB().also { objectB = this }
}
Это уже улучшило бы то, что у вас есть. Теперь вы можете сделать это:
objectA.requireObjectB().requireObjectC().requireObjectD().property = 1234
Для лучшей инкапсуляции каждый объект в дереве должен иметь функцию publi c для выполнения того, что вы делаете, поэтому вам не нужно вызывать глубоко в цепь. Вызывающий класс не должен иметь глубоких знаний о тонкостях дерева объектов с пятью глубинами. Любое незначительное изменение класса в середине дерева может взорвать ваш проект везде, где что-то пытается изменить что-то глубоко в дереве. Но если у вас есть функции publi c на всех этих классах, вы можете гарантировать, что изменения безопасны для выполнения, пока функции publi c все еще выполняют то, что от них ожидается.