Как мне абстрагировать слой домена от слоя персистентности в Scala

ОБНОВИТЬ: Я отредактировал заголовок и добавил этот текст, чтобы лучше объяснить, чего я пытаюсь достичь: я пытаюсь создать новое приложение с нуля, но не хочу, чтобы бизнес-уровень знал о слое персистентности, точно так же не хотелось бы, чтобы бизнес-уровень знал о REST API-уровне. Ниже приведен пример слоя постоянства, который я хотел бы использовать. Я ищу хороший совет по интеграции с этим, то есть мне нужна помощь с дизайном / архитектурой, чтобы четко разделить обязанности между бизнес-логикой и логикой постоянства. Может быть, концепция вдоль линии маршаллинга и демаршаллинга объектов персистентности в доменные объекты.

С SLICK (a.k.a. ScalaQuery)тестовый примерэто то, как вы создаете связь базы данных «многие ко многим». Это создаст 3 таблицы: a, b и a_to_b, где a_to_b хранит ссылки строк в таблице a и b.

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)

Как мойnext шаг, я хотел бы поднять это на один уровень (я все еще хочу использовать SLICK, но красиво обернуть), чтобы работать с объектами. Так что в псевдокоде было бы здорово сделать что-то вроде:

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

Или что-то типа того. У меня есть свои идеи о том, как я могу подойти к этому в Java, но я начинаю понимать, что некоторые из моих объектно-ориентированных идей из чистых ОО-языков начинают меня подводить. Может кто-нибудь дать мне несколько советов о том, как подойти к этой проблеме в Scala.

Например: я создаю простые объекты, которые просто обертывают или расширяют объекты таблицы, и затем включают их (состав) в другой класс, который управляет ими?

Будем весьма благодарны за любые идеи, указания, примеры (пожалуйста), которые помогут мне лучше подойти к этой проблеме как дизайнера и программиста.

Ответы на вопрос(2)

Ваш ответ на вопрос