Wie abstrahiere ich die Domain-Ebene von der Persistenz-Ebene in Scala?

UPDATE: Ich habe den Titel bearbeitet und diesen Text hinzugefügt, um besser zu erklären, was ich erreichen möchte: Ich versuche, eine neue Anwendung von Grund auf zu erstellen, möchte aber nicht, dass die Business-Schicht etwas über die Persistenz weiß Ebenso wenig möchte man, dass die Business-Schicht etwas über eine REST-API-Schicht erfährt. Unten ist ein Beispiel für eine Persistenzschicht, die ich verwenden möchte. Ich bin auf der Suche nach guten Ratschlägen für die Integration, d. H. Ich benötige Hilfe beim Design / der Architektur, um die Verantwortlichkeiten sauber zwischen Geschäftslogik und Persistenzlogik zu trennen. Vielleicht ein Konzept im Sinne des Marshallings und des Unmarshallings von Persistenzobjekten zu Domänenobjekten.

Aus einer SLICK (a.k.a. ScalaQuery)TestbeispielAuf diese Weise erstellen Sie eine Viele-zu-Viele-Datenbankbeziehung. Dadurch werden drei Tabellen erstellt: a, b und a_to_b, wobei a_to_b die Links der Zeilen in Tabelle a und b enthält.

object A extends Table[(Int, String)]("a") {
  def id = column[Int]("id", O.PrimaryKey)
  def s = column[String]("s")
  def * = id ~ s
  def bs = AToB.filter(_.aId === id).flatMap(_.bFK)
}

object B extends Table[(Int, String)]("b") {
  def id = column[Int]("id", O.PrimaryKey)
  def s = column[String]("s")
  def * = id ~ s
  def as = AToB.filter(_.bId === id).flatMap(_.aFK)
}

object AToB extends Table[(Int, Int)]("a_to_b") {
  def aId = column[Int]("a")
  def bId = column[Int]("b")
  def * = aId ~ bId
  def aFK = foreignKey("a_fk", aId, A)(a => a.id)
  def bFK = foreignKey("b_fk", bId, B)(b => b.id)
}

(A.ddl ++ B.ddl ++ AToB.ddl).create
A.insertAll(1 -> "a", 2 -> "b", 3 -> "c")
B.insertAll(1 -> "x", 2 -> "y", 3 -> "z")
AToB.insertAll(1 -> 1, 1 -> 2, 2 -> 2, 2 -> 3)

val q1 = for {
  a <- A if a.id >= 2
  b <- a.bs
} yield (a.s, b.s)
q1.foreach(x => println(" "+x))
assertEquals(Set(("b","y"), ("b","z")), q1.list.toSet)

Als meineNächster Schritt, ich möchte dies eine Ebene aufsteigen (ich möchte immer noch SLICK verwenden, aber es schön verpacken), um mit Objekten zu arbeiten. Im Pseudocode wäre es also großartig, etwas zu tun wie:

objectOfTypeA.save()
objectOfTypeB.save()
linkAtoB.save(ojectOfTypeA, objectOfTypeB)

Oder sowas ähnliches. Ich habe meine Ideen, wie ich dies in Java angehen könnte, aber ich beginne zu erkennen, dass einige meiner objektorientierten Ideen aus reinen OO-Sprachen mir allmählich nicht mehr weiterhelfen. Kann mir jemand bitte einige Hinweise geben, wie man dieses Problem in Scala angeht.

Beispiel: erstelle ich einfache Objekte, die nur die Tabellenobjekte umschließen oder erweitern, und binde diese (Komposition) dann in eine andere Klasse ein, die sie verwaltet?

Alle Ideen, Anleitungen, Beispiele (bitte), die mir helfen, dieses Problem als Designer und Programmierer besser anzugehen, werden sehr geschätzt.

Antworten auf die Frage(2)

Ihre Antwort auf die Frage