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

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

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


person Jeb    schedule 20.09.2010    source источник


Ответы (4)


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

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

Также прочтите эту статью, имеющую отношение к делу если тебе хочется принять красную таблетку. :)

person Alex Cruise    schedule 20.09.2010
comment
И вы можете красиво извлечь это в черту Publisher. - person Alexey Romanov; 21.09.2010

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

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

Обновление от 27 апреля 2015 г. Существует также более свежий Устаревание шаблона Observer с помощью Scala.React» Майера и Одерского.

person Alexey Romanov    schedule 20.09.2010
comment
Не могли бы вы привести пример этого? - person cdmckay; 29.05.2014
comment
Пакет @cdmckay scala.swing в стандартной библиотеке основан на нем. См. его примеры и учебные пособия. - person Alexey Romanov; 29.05.2014

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

person Brian    schedule 20.09.2010

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

person IttayD    schedule 12.10.2010
comment
@ziggystar, а? Каков был ваш опыт? - person Haakon; 04.07.2013
comment
Я думаю, что я не заставил его работать или это раздражало в использовании. Сейчас я использую сторонние библиотеки или запускаю свои собственные. - person ziggystar; 04.07.2013