Pour presque tous ces cas, il y a Scala solutions alternatives certains mais pas tous les cas d'utilisation de ces modèles. Tout cela est de l'OMI, bien sûr, mais:
Creational Modèles
Constructeur
Scala peut le faire plus élégamment avec les types génériques que peut Java, mais l'idée générale est la même. En Scala, le modèle le plus simplement mis en œuvre comme suit:
trait Status
trait Done extends Status
trait Need extends Status
case class Built(a: Int, b: String) {}
class Builder[A <: Status, B <: Status] private () {
private var built = Built(0,"")
def setA(a0: Int) = { built = built.copy(a = a0); this.asInstanceOf[Builder[Done,B]] }
def setB(b0: String) = { built = built.copy(b = b0); this.asInstanceOf[Builder[A,Done]] }
def result(implicit ev: Builder[A,B] <:< Builder[Done,Done]) = built
}
object Builder {
def apply() = new Builder[Need, Need]
}
(Si vous essayez ceci dans le REPL, assurez-vous que la classe et l'objet Builder sont définies dans le même bloc, c'est à dire utiliser :paste
.) La combinaison de la vérification des types avec <:<
, type générique arguments, et la méthode de copie des classes de cas de faire une très puissante combinaison.
Méthode de fabrique (et Abstraite de l'Usine de la Méthode)
Méthodes de fabrique' utilisation principale est de garder vos types de droit; sinon, vous pouvez aussi bien utiliser des constructeurs. Avec Scala, le puissant système de type, vous n'avez pas besoin d'aide pour garder vos types de droit, de sorte que vous pourriez aussi bien utiliser le constructeur ou un apply
méthode dans le compagnon objet de votre classe et de créer des choses de cette façon. Dans le compagnon de l'objet-cas en particulier, il n'est pas plus difficile de garder cette interface cohérente que c'est pour garder l'interface de l'usine, objet conforme. Ainsi, la plupart de la motivation pour les objets de fabrique est allé.
De même, de nombreux cas de résumé de méthodes de fabrique peut être remplacée par avoir un compagnon objet hérite d'un trait.
Prototype
Bien sûr méthodes de remplacement et du genre, ont leur place dans la Scala. Cependant, les exemples utilisés pour le Prototype de modèle sur les Modèles de Conception de site web sont plutôt déconseillée en Scala (ou Java OMI). Cependant, si vous souhaitez avoir une super-classe de sélectionner les actions basées sur ses sous-classes plutôt que de les laisser décider pour eux-mêmes, vous devez utiliser match
plutôt que le maladroit instanceof
tests.
Singleton
Scala embrasse avec object
. Ils sont des singletons--l'utiliser et en profiter!
Les Modèles Structurels
Adaptateur
Scala trait
offre beaucoup plus de puissance, ici, plutôt que de créer une classe qui implémente une interface, par exemple, vous pouvez créer un trait qui implémente seulement une partie de l'interface, laissant le reste pour vous à définir. Par exemple, java.awt.event.MouseMotionListener
vous oblige à remplir deux méthodes:
def mouseDragged(me: java.awt.event.MouseEvent)
def mouseMoved(me: java.awt.event.MouseEvent)
Peut-être que vous voulez ignorer les faisant glisser. Ensuite, vous écrivez un trait
:
trait MouseMoveListener extends java.awt.event.MouseMotionListener {
def mouseDragged(me: java.awt.event.MouseEvent) {}
}
Maintenant, vous pouvez mettre en œuvre seulement mouseMoved
lorsque vous héritez de cette. Donc: modèle similaire, mais beaucoup plus de puissance avec Scala.
Pont
Vous pouvez écrire des ponts en Scala. C'est une énorme quantité de passe-partout, mais pas tout à fait aussi mauvais que dans Java. Je ne recommande pas systématiquement l'aide de cette méthode de l'abstraction; pensez à vos interfaces soigneusement d'abord. Gardez à l'esprit que, avec l'augmentation de la puissance de traits de caractère que vous pouvez souvent utiliser ceux de simplifier une interface plus élaborée dans un endroit où vous pourriez être tenté d'écrire un pont.
Dans certains cas, vous pouvez écrire une interface transformateur au lieu de Java pont de modèle. Par exemple, vous voulez peut-être traiter les dragues et les mouvements de la souris en utilisant la même interface avec seulement un indicateur booléen de les distinguer. Ensuite, vous pouvez
trait MouseMotioner extends java.awt.event.MouseMotionListener {
def mouseMotion(me: java.awt.event.MouseEvent, drag: Boolean): Unit
def mouseMoved(me: java.awt.event.MouseEvent) { mouseMotion(me, false) }
def mouseDragged(me: java.awt.event.MouseEvent) { mouseDragged(me, true) }
}
Cela vous permet de sauter la majorité du pont modèle passe-partout, tandis que la réalisation d'un degré élevé de mise en œuvre de l'indépendance et de laisser vos classes d'obéir à l'interface d'origine (si vous n'avez pas à garder l'emballage et déballage de mer).
Composite
Le diagramme composite est particulièrement facile à réaliser avec des classes de cas, bien que faisant des mises à jour est plutôt ardu. Il est également précieux dans Scala et Java.
Décorateur
Les décorateurs sont difficiles. D'habitude vous ne souhaitez pas utiliser les mêmes méthodes sur une autre classe dans le cas où l'héritage n'est pas exactement ce que vous voulez, ce que vous voulez vraiment est une autre méthode de la même classe qui fait ce que vous voulez au lieu de la valeur par défaut de la chose. L' enrichir ma bibliothèque de modèle est souvent un supérieur de substitution.
Façade
Façade fonctionne mieux dans le Scala qu'en Java, car vous pouvez avoir des traits réaliser partielle implémentations autour de sorte que vous n'avez pas à faire tout le travail vous-même lorsque vous les combinez.
Poids mouche
Bien que le poids mouche idée est aussi valable en Scala, Java, vous avez un couple de plus à votre disposition des outils pour la mettre en œuvre: lazy val
, d'où une variable n'est pas créé, sauf si c'est vraiment nécessaire (et, par la suite, est réutilisé), et by-name parameters
, où vous seulement faire le travail nécessaire à la création d'un argument de fonction si la fonction utilise cette valeur. Cela dit, dans certains cas, la Java modèle est inchangé.
Proxy
Fonctionne de la même manière dans Scala comme Java.
Les Modèles De Comportement
La chaîne de responsabilité
Dans les cas où vous pouvez lister les parties responsables dans l'ordre, vous pouvez
xs.find(_.handleMessage(m))
en supposant que tout le monde a un handleMessage
méthode qui retourne true
si le message a été traité. Si vous souhaitez muter le message comme il va, utiliser un pli à la place.
Depuis, il est facile de déposer les parties responsables en Buffer
de la sorte, l'élaboration du cadre utilisé dans les solutions Java a rarement une place en Scala.
Commande
Ce modèle est presque entièrement remplacée par des fonctions. Par exemple, au lieu de tout
public interface ChangeListener extends EventListener {
void stateChanged(ChangeEvent e)
}
...
void addChangeListener(ChangeListener listener) { ... }
il vous suffit de
def onChange(f: ChangeEvent => Unit)
Interprète
Scala offre analyseur combinators qui sont considérablement plus puissant que le simple interprète proposé comme un Modèle de Conception.
Itérateur
Scala a Iterator
dans sa bibliothèque standard. Il est presque banal de faire votre propre classe d'étendre Iterator
ou Iterable
; ce dernier est généralement préférable car elle permet de réutiliser trivial. Certainement une bonne idée, mais si simple, j'ai peine à appeler ça un motif.
Médiateur
Cela fonctionne bien en Scala, mais est généralement utile pour mutable données, et même les médiateurs peuvent tomber à l'encontre des conditions de course et ces si pas utilisé avec précaution. Au lieu de cela, essayez si possible d'avoir vos données tous stockés dans un immuable de la collecte, de la classe de cas, ou que ce soit, et, lors d'une mise à jour qui nécessite des changements coordonnés, changement de toutes les choses en même temps. Ce ne sera pas vous aider à l'interface avec d' javax.swing
, mais est par ailleurs largement applicable:
case class Entry(s: String, d: Double, notes: Option[String]) {}
def parse(s0: String, old: Entry) = {
try { old.copy(s = s0, d = s0.toDouble) }
catch { case e: Exception => old }
}
Enregistrer le médiateur modèle pour quand vous avez besoin de gérer de multiples relations différentes (un médiateur pour chacun), ou lorsque vous avez des données mutable.
Memento
lazy val
est presque idéale pour de nombreuses applications les plus simples de la memento motif, par exemple
class OneRandom {
lazy val value = scala.util.Random.nextInt
}
val r = new OneRandom
r.value // Evaluated here
r.value // Same value returned again
Vous pouvez créer une petite classe spécifiquement pour les paresseux de l'évaluation:
class Lazily[A](a: => A) {
lazy val value = a
}
val r = Lazily(scala.util.Random.nextInt)
// not actually called until/unless we ask for r.value
Observateur
C'est un fragile de motif au mieux. Favoriser, chaque fois que possible, garder immuable de l'état (voir le Médiateur), ou en utilisant les acteurs, où un acteur envoie des messages à tous les autres concernant le changement d'état, mais où chaque acteur peut supporter d'être hors de date.
État
Ceci est également utile dans la Scala, et est en fait la meilleure façon de créer des énumérations lorsqu'il est appliqué à methodless traits:
sealed trait DayOfWeek
final trait Sunday extends DayOfWeek
...
final trait Saturday extends DayOfWeek
(fréquence vous souhaitez les jours de la semaine pour faire quelque chose pour justifier ce montant réutilisable).
Stratégie
C'est presque entièrement remplacé par des méthodes prennent des fonctions qui mettent en œuvre une stratégie, et de fournir des fonctions de choisir à partir.
def printElapsedTime(t: Long, rounding: Double => Long = math.round) {
println(rounding(t*0.001))
}
printElapsedTime(1700, math.floor) // Change strategy
Méthode De Modèle
Les Traits offrent beaucoup plus de possibilités là que, il est préférable de considérer un autre motif. Vous pouvez remplir autant de code que vous pouvez à partir d'autant d'informations que vous avez à votre niveau d'abstraction. Je ne voudrais vraiment appeler ça de la même chose.
Visiteur
Entre structurels de frappe et de la conversion implicite, Scala a étonnamment plus de capacités que Java est typique des habitudes des visiteurs. Il n'y a pas de point à l'aide du modèle original; vous aurez juste se laisser distraire de la bonne façon de le faire. De nombreux exemples sont vraiment juste qui souhaitent y avait une fonction définie sur la chose qu'il soit visité, qui Scala peut faire pour vous trivialement (c'est à dire convertir une méthode arbitraire à une fonction).