【发布时间】:2011-04-14 21:40:18
【问题描述】:
通常,在 Java 中,当我有一个向其他对象提供某种通知的对象时,我将使用侦听器/观察者模式。
有没有更类似于 Scala 的方式来做到这一点?我应该在 Scala 中使用这种模式,还是在我应该利用的语言中加入其他东西?
【问题讨论】:
标签: scala listener observer-pattern
通常,在 Java 中,当我有一个向其他对象提供某种通知的对象时,我将使用侦听器/观察者模式。
有没有更类似于 Scala 的方式来做到这一点?我应该在 Scala 中使用这种模式,还是在我应该利用的语言中加入其他东西?
【问题讨论】:
标签: scala listener observer-pattern
您仍然可以累积回调列表,但您可以让它们成为函数,而不必再想出另一个单一的方法接口。
例如
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。 :)
【讨论】:
Publisher 特征中。
有没有更类似于 Scala 的方式来做到这一点?
是的。阅读 Ingo Maier、Tiark Rompf 和 Martin Odersky 的论文Deprecating the Observer Pattern。
2015 年 4 月 27 日更新: 还有一个更新的 Deprecating the Observer Pattern with Scala.React 由 Maier 和 Odersky 撰写。
【讨论】:
scala.swing 标准库中的包就是基于它。查看其示例和教程。
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))
}
这个 sn-p 非常类似于在 Java 中找到的带有一些 Scala 特性的。这是来自 Dean Wampler 的博客 - http://blog.objectmentor.com/articles/2008/08/03/the-seductions-of-scala-part-i
这使用了一些 Scala 特性,例如用 [S] 表示的泛型,类似于 Java 接口但更强大的特性,:: 将观察者添加到观察者列表中,以及使用 _ 的参数的 foreach对当前观察者求值。
【讨论】:
您可以使用 scala.collection.mutable.Publisher 和 scala.collection.mutable.Subscriber 来创建 pub/sub 实现
【讨论】: