2010-09-20 7 views
14

Généralement, en Java, lorsque j'ai un objet qui fournit une sorte de notification à d'autres objets, j'utilise le pattern Listener/Observer.Scala Listener/Observer

Existe-t-il un moyen plus semblable à Scala pour ce faire? Devrais-je utiliser ce modèle dans Scala, ou y a-t-il quelque chose d'autre dans le langage dont je devrais profiter?

Répondre

18

Vous pouvez toujours accumuler une liste de rappels, mais vous pouvez simplement en faire des fonctions au lieu d'avoir à créer une autre interface de méthode unique.

par exemple.

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

lire également ce this somewhat-related paper si vous avez envie de prendre la pilule rouge. :)

+5

Et vous pouvez extraire ce bien dans un trait 'Publisher'. –

17

Existe-t-il un moyen plus similaire à Scala pour ce faire?

Oui. Lire l'article Deprecating the Observer Pattern par Ingo Maier, Tiark Rompf et Martin Odersky.

Mise à jour 27-Apt-2015: Il existe également un plus récent Deprecating the Observer Pattern with Scala.React de Maier et Odersky.

+0

Pourriez-vous donner un exemple? – cdmckay

+0

@cdmckay Le paquet 'scala.swing' de la bibliothèque standard est basé dessus. Voir ses exemples et tutoriels. –

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

Cet extrait est assez similaire à ce que l'on trouverait dans Java avec certaines fonctionnalités de Scala. Ceci utilise le blog de Dean Wampler - http://blog.objectmentor.com/articles/2008/08/03/the-seductions-of-scala-part-i

Ceci utilise certaines caractéristiques de Scala telles que les génériques comme indiqué par [S], traits qui sont comme les interfaces Java mais plus puissants, :: pour ajouter un observateur à la liste des observateurs, et un foreach avec le paramètre utilisant un _ qui évalue à l'observateur actuel.

2

Vous pouvez utiliser scala.collection.mutable.Publisher et scala.collection.mutable.Subscriber pour créer un pub/sous la mise en œuvre

+0

J'ai essayé cette fois ... – ziggystar

+0

@ziggystar, et? Quelle a été ton expérience? – Haakon

+0

Je pense que je ne l'ai pas eu pour travailler ou c'était ennuyeux à utiliser. J'utilise maintenant des bibliothèques tierces ou je mets les miennes. – ziggystar