Scala Listener / Observer

时间:2010-09-20 20:58:44

标签: scala listener observer-pattern

通常,在Java中,当我有一个向其他对象提供某种通知的对象时,我会使用Listener / Observer模式。

有更多类似Scala的方法吗?我应该在Scala中使用这种模式,还是我应该利用的语言中还有其他东西?

4 个答案:

答案 0 :(得分:20)

你仍然可以累积一个回调列表,但你可以让它们成为函数,而不必再提出另一个单一的方法接口。

e.g。

case class MyEvent(...)

object Foo { 
  var listeners: List[MyEvent => ()] = Nil

  def listen(listener: MyEvent => ()) {
    listeners ::= listener
  }

  def notify(ev: MyEvent) = for (l <- listeners) l(ev) 
}

如果您想服用红色药丸,请阅读此this somewhat-related paper。 :)

答案 1 :(得分:17)

  

有更多类似Scala的方法吗?

是。阅读Ingo Maier,Tiark Rompf和Martin Odersky的论文Deprecating the Observer Pattern

更新27-Apt-2015: Maier和Odersky还有一个更新的Deprecating the Observer Pattern with Scala.React

答案 2 :(得分:4)

trait Observer[S] {
     def receiveUpdate(subject: S);
}

trait Subject[S] {
     this: S =>
     private var observers: List[Observer[S]] = Nil
     def addObserver(observer: Observer[S]) = observers = observer :: observers

     def notifyObservers() = observers.foreach(_.receiveUpdate(this))
}

这个代码段非常类似于Java中的一些Scala功能。这是来自Dean Wampler的博客 - http://blog.objectmentor.com/articles/2008/08/03/the-seductions-of-scala-part-i

这使用了一些Scala功能,例如[S]表示的泛型,类似Java接口但更强大的特性,::将观察者添加到观察者列表中,以及带参数的foreach使用_评估当前的观察者。

答案 3 :(得分:2)

您可以使用scala.collection.mutable.Publisher和scala.collection.mutable.Subscriber来创建pub / sub实现