我正在尝试创建一个类似的侦听器设计模式:
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
和listener1
时最初等于listener2
。
我如何克服这个问题?
编辑:我尝试了以下内容:
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
}
使用_
进行初始化而不是'null'或'Nil'会使编译器在创建listeners
和listener1
后不会覆盖listener2
。
答案 0 :(得分:2)
在lazy value和mutable collection的帮助下:
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
方法将缓冲区转换为它。