Перекрестные ссылки и порядок инициализации объекта

У меня есть следующий код:

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
  }
}
Другие вопросы по тегам