Ich komme aus einem OO-Hintergrund (C #, Javascript) und Scala ist mein erster Ausflug in FP.
Aufgrund meines Hintergrunds habe ich Probleme, ein Domänenmodell zu realisieren, das zu meinem Domänenproblem passt, und entspricht auch den guten Praktiken für FP, wie zum Beispiel minimaler Änderbarkeit im Code.
Zuerst eine kurze Beschreibung meines Domain-Problems, wie es jetzt ist.
Event, Tournament, User, and Team
Teams
bestehen aus Users
Teams
als auch Users
können an Tournaments
teilnehmen, die an einem Event
stattfinden.
Events
bestehen aus Users
und Tournaments
Teams
und Users
, die über Tournaments
und Events
konkurrieren, sind ein wichtiges Feature. Angesichts dieser Beschreibung des Problems ist meine ursprüngliche Idee für die Domäne, Objekte zu erstellen, bei denen bidirektionale, zyklische Beziehungen die Norm sind - etwas, das einem Graph ähnelt. Mein Denkansatz ist, dass der Zugriff auf alle zugehörigen Objekte für ein gegebenes Objekt den einfachsten Weg bietet, Ansichten für meine Daten zu programmieren und zu manipulieren.
%Vor%Wie auch immer ich in die Best Practices von FP eingetaucht bin, ich habe festgestellt, dass mein Denkprozess mit FP-Prinzipien unvereinbar ist. Zirkelverweise sind verpönt und scheinen fast ein Unmöglichkeit mit unveränderlichen Objekten.
Angesichts dessen kämpfe ich jetzt damit, wie ich meine Domäne umgestalten kann, um die Anforderungen für gute FP zu erfüllen, während ich immer noch eine vernünftige Organisation der "realen Weltobjekte" in der Domäne beibehalte.
Einige Optionen, die ich in Betracht gezogen habe
Also habe ich Probleme damit, entweder meine Implementierung oder mein ursprüngliches Modell zu ändern, um die Kopplung zu erreichen, die ich brauche, aber auf die "richtige Art und Weise" für Scala. Wie gehe ich an dieses Problem heran?
TL; DR - Wie modelliere ich eine Domäne mit guten FP-Praktiken, wenn die Domäne im Kern bidirektionalen Zugriff und Wandlungsfähigkeit erfordert?
Wenn Sie davon ausgehen, dass Ihr Domänenmodell von einer Datenbank unterstützt wird, würde ich in dem oben hervorgehobenen Fall die Eigenschaften "Teams", "Ereignisse" und "Turniere" Ihrer Benutzerklasse definieren, die die entsprechenden Objekte aus der Datenbank abruft Datenbank (Sie könnten eine Caching-Strategie implementieren, wenn Sie über exzessive db-Aufrufe besorgt sind). Es könnte etwa so aussehen:
%Vor%Eine andere Möglichkeit, dies zu sagen, könnte sein, dass Ihre zyklischen Abhängigkeiten eine einzige "autoritative" Richtung haben, während Referenzen in die andere Richtung daraus berechnet werden. Wenn Sie beispielsweise einen Benutzer zu einem Turnier hinzufügen, muss Ihre Funktion nur ein neues Turnierobjekt (mit dem hinzugefügten Benutzer) und nicht ein neues Turnierobjekt und ein neues Benutzerobjekt zurückgeben. Anstelle einer expliziten Modellierung der Verknüpfungstabelle TournamentUser könnte Tournament einfach eine Liste von User / Boolean-Tupeln enthalten.
Eine andere Option könnte sein, Objektive zu verwenden, um Ihr Domänenmodell zu ändern, aber ich habe sie nicht implementiert eine Situation wie diese. Vielleicht könnte jemand mit mehr Erfahrung in FP hier auf ihre Anwendbarkeit eingehen.
Tags und Links scala functional-programming immutability cyclic-reference domain-model