Scala Listener / Observer - PullRequest
       24

Scala Listener / Observer

15 голосов
/ 21 сентября 2010

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

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

Ответы [ 4 ]

20 голосов
/ 21 сентября 2010

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

например.

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

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

17 голосов
/ 21 сентября 2010

Есть ли более похожий на Scala способ сделать это?

Да. Прочтите статью Инго Майера, Тиарка Ромпфа и Мартина Одерского Обесценивающий образец наблюдателя .

Обновление 27-Апт-2015: Существует также более поздняя версия , которая устарела в Наблюдателе с помощью Scala.React от Майера и Одерского.

4 голосов
/ 21 сентября 2010
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. Это из блога Дина Уэмплера - http://blog.objectmentor.com/articles/2008/08/03/the-seductions-of-scala-part-i

При этом используются некоторые функции Scala, такие как обобщения, обозначенные [S], признаки, которые похожи на интерфейсы Java, но более мощные, :: для добавления наблюдателя в список наблюдателей, и foreach с параметром, использующий _ который оценивает текущий наблюдатель.

2 голосов
/ 12 октября 2010

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

...