Перекрестные ссылки и порядок инициализации объекта
У меня есть следующий код:
abstract class SuperClass (cs: Seq[C]) {
def init {}
}
object A extends SuperClass(Seq(B, C))
object B extends SuperClass(Seq(A, D))
object C extends SuperClass(Seq(A, B))
object D extends SuperClass(Seq(C, B, A))
object E extends SuperClass(Seq(B, A, B))
object Initializer {
def init {
A.init
B.init
C.init
D.init
E.init
}
}
поэтому в начале, потому что каждый объект имеет внутри еще несколько вещей для инициализации, я называю
Initializer.init
а затем в какой-то момент в программе, когда я использую cs
Параметр объекта, я получаю NullPointerException
потому что один из объектов, указанных в Seq
действительно null
(распечатка на консоль показывает, что). А именно ссылки на объекты, которые имеют свои init
позвонил позже, чем init
из других объектов, которые ссылаются на них, как правило, установлены null
,
Это интересная ситуация. У меня здесь есть произвольные перекрестные ссылки произвольно, и я не знаю, как правильно реализовать инициализацию, не выводя ее полностью на внешний метод (что в любом случае является нарушением инкапсуляции). Тем более что пользователям может быть предоставлена возможность создавать свои собственные синглеты, расширяющие SuperClass
учебный класс.
Каков наилучший способ сделать это с как можно меньшим количеством шаблонов?
1 ответ
Я придумал следующее решение. Ну, это наполовину дубликат Instantiating неизменяемых парных объектов, но зависимости, определенные Seq, являются дополнительным измерением.
abstract class SuperClass (cs: => Seq[SuperClass]) {
SuperClass.collected += this
def init {}
}
object SuperClass {
private val collected = ListBuffer[SuperClass]()
def init = collected.foreach(_.init)
}
object Initializer {
def init {
A // access the root object
SuperClass.init // call init on all automatically created dependent objects
}
}