2013-02-09 122 views
0

我有以下代码:对象的交叉引用和初始化顺序

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(打印到控制台sh那)。也就是说,引用它们的参照物的init比参照它们的其他物体的init更倾向于设定为null

这是一个有趣的情况。我有一个任意对任意的任意交叉引用,我不知道如何正确地实现初始化,而无需完全将其发布到外部方法(无论如何,这是一个封装拆分)。特别是,用户可能被赋予创建自己的单身人士的能力,扩展SuperClass类。

哪种方法最好的方法是尽可能减少样板?

+0

[实例化不可变配对对象]的可能重复(http://stackoverflow.com/questions/7507965/instantiating-immutable-paired-objects)。简而言之:'抽象类SuperClass(cs:=> Seq [SuperClass])' – sschaef 2013-02-09 16:08:32

+0

@sschaef:umm ..你试过了吗?我无法让它工作。无论如何,Seq是在通过名称之前构建的。根据鸡蛋的例子,我必须让Seq在构造时变得懒惰。但是我将它传递给构造函数来构造它,所以我不能让它变得懒惰。而将其定义为其他地方的懒惰也不会看起来太吸引人......是的,我只是不明白! – noncom 2013-02-10 16:40:15

+0

什么不适合你?这工作:https://gist.github.com/sschaef/4750334 – sschaef 2013-02-10 17:32:05

回答

1

我想出了以下解决方案。那么它是Instantiating immutable paired objects的一半,但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 
    } 
} 
+0

那么,你已经改进了初始化例程..但似乎没有解决初始化顺序问题,据我了解,它只是自动初始化..也看到我对sschaef评论原始问题的评论... – noncom 2013-02-10 16:43:05

+0

谁说对象必须按顺序初始化?另外 - 是的 - 我的解决方案只会初始化连接到A的那些对象。但这比单独初始化每个对象更通用一些。你可能也会有一个起点或根对象在应用程序中使用......所以。这取决于整个事情将如何使用。你上面的评论表明你不明白 - 好的... – 2013-02-10 16:56:48