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.
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?
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 paper if you feel like taking the red pill. :)
Is there a more Scala-like way to do this?
Yes. Read the paper Deprecating the Observer Pattern by Ingo Maier, Tiark Rompf, and Martin Odersky.
Update 27-Apt-2015: There is also a more recent Deprecating the Observer Pattern with Scala.React by Maier and Odersky.
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
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.
You can use scala.collection.mutable.Publisher and scala.collection.mutable.Subscriber to create a pub/sub implementation
来源:https://stackoverflow.com/questions/3755453/scala-listener-observer