Scala Слушатель/Наблюдатель

Как правило, на Java, когда у меня есть объект, который предоставляет какое-то уведомление другим объектам, я использую шаблон Listener/Observer.

Есть ли способ Scala-like? Должен ли я использовать этот шаблон в Scala, или есть что-то еще, испеченное на языке, который я должен использовать?

Ответы

Ответ 1

Вы все еще можете скопировать список обратных вызовов, но вы можете просто сделать их функциями вместо того, чтобы придумать еще один интерфейс метода.

например.

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

Также прочитайте это эту несколько связанную бумагу, если вам хочется взять красную таблетку.:)

Ответ 3

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 с параметром, используя _, который оценивается текущим наблюдателем.

Ответ 4

Вы можете использовать scala.collection.mutable.Publisher и scala.collection.mutable.Subscriber для создания pub/sub-реализации