1

我正在尝试创建这样的侦听器设计模式:

abstract class Listener(g: Engine) {
  g.addListener(this)
}
class Listener1(g: Engine) extends Listener(g)
class Listener2(g: Engine) extends Listener(g)

class Engine {
  val listener1 = new Listener1(this)
  val listener2 = new Listener2(this)  

  var listeners: List[Listener] = Nil
  def addListener(g: Listener) = {
    listeners = g::listeners
  }
}

但是如果失败并带有NullPointerException, 因为listeners最初等于创建null时间listener1listener2创建时间。

我该如何克服这个问题?

编辑:我尝试了以下方法:

  def addListener(g: Listener) = {
    if(listeners == null) {
      listeners = List(g)
    } else {
      listeners = g::listeners
    }
  }

但问题是类初始化后,listeners = Nil。我需要一个更好的设计模式来实现我的目标。

解决方案:不使用惰性 val 或可变集合:

var listeners: List[Listener] = _
def addListener(g: Listener) = {
  if(listeners == null) 
    listeners = List(g)
  else
    listeners = g::listeners
}

使用_for 初始化而不是 'null' 或 'Nil' 使编译器在创建listeners之后不会覆盖。listener1listener2

4

1 回答 1

2

借助惰性值可变集合

class Engine {
  val listener1 = new Listener1(this)
  val listener2 = new Listener2(this)  

  lazy val listeners = collection.mutable.ListBuffer.empty[Listener]
  def addListener(g: Listener) {
    listeners += g
  }
}

如果您在某个地方急需不可变列表,只需使用调用位置.toList中的方法将缓冲区转换为它。

于 2013-04-25T12:20:57.700 回答