Scala 监听器/观察器

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3755453/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-22 02:26:02  来源:igfitidea点击:

Scala Listener/Observer

scalalistenerobserver-pattern

提问by Jeb

Typically, in Java, when I've got an object who's providing some sort of notification to other objects, I'll employ the Listener/Observer pattern.

通常,在 Java 中,当我有一个对象向其他对象提供某种通知时,我将使用侦听器/观察者模式。

Is there a more Scala-like way to do this? Should I be using this pattern in Scala, or is there something else baked into the language I should be taking advantage of?

有没有更像 Scala 的方法来做到这一点?我应该在 Scala 中使用这种模式,还是应该在我应该利用的语言中加入其他东西?

回答by Alex Cruise

You can still accumulate a list of callbacks, but you can just make them functions instead of having to come up with yet another single method interface.

您仍然可以累积一个回调列表,但您可以让它们发挥作用,而不必再想出另一个单一的方法接口。

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) 
}

Also read this this somewhat-related paperif you feel like taking the red pill. :)

如果您想服用红色药丸,也可以阅读这篇与此相关的论文。:)

回答by Alexey Romanov

Is there a more Scala-like way to do this?

有没有更像 Scala 的方法来做到这一点?

Yes. Read the paper Deprecating the Observer Patternby Ingo Maier, Tiark Rompf, and Martin Odersky.

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

Update 27-Apt-2015:There is also a more recent Deprecating the Observer Pattern with Scala.Reactby Maier and Odersky.

2015 年 27 月更新:Maier 和 Odersky还发表了更新的Deprecating the Observer Pattern with Scala.React

回答by Brian

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))
}

This snippet is pretty similar to what one would find in Java with some Scala features. This is from Dean Wampler's blog - http://blog.objectmentor.com/articles/2008/08/03/the-seductions-of-scala-part-i

这个片段与在 Java 中发现的具有一些 Scala 特性的片段非常相似。这是来自 Dean Wampler 的博客 - http://blog.objectmentor.com/articles/2008/08/03/the-seductions-of-scala-part-i

This uses some Scala features such as generics as denoted by the [S], traits which are like Java interfaces but more powerful, :: to prepend an observer to the list of observers, and a foreach with the parameter using an _ which evaluates to the current observer.

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

回答by IttayD

You can use scala.collection.mutable.Publisher and scala.collection.mutable.Subscriber to create a pub/sub implementation

您可以使用 scala.collection.mutable.Publisher 和 scala.collection.mutable.Subscriber 来创建发布/订阅实现