Frage

In meinem Web-Anwendung berechtigter Benutzer hat mindestens 4 „Facetten“. Http sitzungsbezogene Daten, persistente Daten, Facebook Daten, Runtime-Geschäftsdaten

Ich habe für mindestens zwei Gründen statt Züge mit Fallklasse Zusammensetzung beschlossen gehen:

  • Züge Mischen kann zu Namenskonflikten
  • Ich will die freie Fall Klasse Goodies wie Pattern-Matching und Kopiermethode

Ich möchte zu diesem Thema erfahren scalaists Meinungen kennen. Es sieht aus wie Züge und / oder Kuchen Muster sollten für solche Aufgaben geeignet sein, aber wie ich schon oben erwähnt sind Probleme ... Es ist offensichtlich, dass nicht nur ich es schnell implementieren möchten und einfach, sondern auch in der Tiefe zu verstehen, für die Verwendung von in Zukunft.

So hat meine Entscheidung irgendwelche Fehler und Missverständnisse oder ist es richtig? Verwandte Code sieht wie folgt aus:


case class FacebookUserInfo(name: String, friends: List[Long])
case class HttpUserInfo(sessionId: String, lastInteractionTime: Long, reconnect: Boolean)
case class RuntimeQuizUserInfo(recentScore: Int)
trait UserState {
  def db: User
  def http: HttpUserInfo
}

case class ConnectingUser(db: User, http: HttpUserInfo) extends UserState
case class DisconnectedUser(db: User, http: HttpUserInfo, facebook: Option[FacebookUserInfo]) extends UserState
case class AuthorizedUser(db: User, http: HttpUserInfo, facebook: FacebookUserInfo,
                          quiz: RuntimeQuizUserInfo) extends UserState
War es hilfreich?

Lösung

Die dritte Option ist impliziten Wandler aka „ Zuhälter meiner Bibliothek „, was wahrscheinlich nicht notwendig ist, da Sie die Kontrolle über den Code haben.

Es hängt alles davon ab, wie undurchsichtig (oder transparent), die Sie über bestimmte Aspekte Ihrer Aufgabe sein. Sie können sich eine einfache alte Fallklasse für den Rest der Welt, so tun, aber intern machen es durch die Verwendung implicits zusätzliche Arbeit zu tun. Die Verwendung von Fallklasse zu halten Daten angemessen ist, aber ich glaube auch, dass es das gleiche Objekt zu repräsentieren mit drei Klassen (ConnectingUser, DisconnectedUser, AuthenticatedUser), je nach ihrem Zustand der Authentifizierung.

umständlich ist

Für die UserState, könnten Sie einen Extraktor bieten, so dass es wie ein Fallklasse verhält:

object UserState {
  def unapply(state: UserState) = Some(state.db, state.http)
}

Dies kann in einem Spiel Zustand wie folgt verwendet werden:

val user = ConnectingUser(User(), HttpUserInfo("foo", 0, false))
user match {
  case UserState(db, http) => println(http)
}

Andere Tipps

Ich denke, die Antwort ist einfach: Gehen Sie mit Vererbung, solange alles wirklich „gehört“ zu Ihrem Objekt, solange alles in dem gleichen „Problembereich“ ist.

Die Absicht des Kuchen Musters zu Faktor aus Teilen des Objekts, das irgendwie erforderlich ist, ist aber nicht wirklich ein Teil davon, z.B. eine Strategie, eine Dekoration, eine Konfiguration würde eine Kontext usw. Protokollierung ein typisches Beispiel. Im Allgemeinen sprechen wir über Situationen, die Sie nicht wollen, zu „Hard-Wire“ Dinge, z.B. Fälle würden Sie erwägen, einen DI-Framework zu verwenden (wie Guice oder Frühling) in Java. Siehe http://jonasboner.com/2008/ 06.10 / real-world-scala-abhängigkeitsspritz di.html für ein gutes Beispiel.

Eine Frage, die hilft, oft zu entscheiden, was zu tun ist: „Wie kann ich das Objekt Verhalten testen?“. Wenn Sie es schwierig finden, eine geeignete Testumgebung einzurichten, stehen die Chancen, dass Sie die Dinge entkoppeln sollen, und das bedeutet, DI, die oft bequem mit dem Kuchen Muster realisiert werden können.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top