Шаблон проектирования для изменения базы данных для производственной и тестовой сред


Мне нужно импортировать разные библиотеки и делать немного разные вещи в зависимости от использования моего исходного кода, т. е. для запуска и тестирования.

Если у меня есть различные исходные файлы, которые выглядят примерно так для производства:

import scala.slick.driver.PostgresDriver.simple._
import Database.threadLocalSession

case class SomeBusinessObject(...)

Какой хороший способ изменить его на следующий для тестирования (то есть я хотел бы использовать другую базу данных во время тестирования):

import scala.slick.driver.h2.simple._
import Database.threadLocalSession

case class SomeBusinessObject(...)

О, и еще есть класс базы данных, который хранит ключ к любой базе данных, в которой я нахожусь. использование:

import scala.slick.driver.PostgresDriver.simple._

// Use the implicit threadLocalSession
import Database.threadLocalSession

object DB{

  val get = {
      Database.forURL("jdbc:postgresql:test:slick",
                           driver="org.postgresql.Driver",
                           user="postgres",
                           password="xxxx") 
  }
}

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

Обновление:

Задав этот вопрос, я нашел именно то, что искал вГладких примерах . Это действительно аккуратно расставляет его! Я работал над примерами несколько недель назад,но не мог вспомнить, где я это видел.

1 2

1 ответ:

Вы можете построить на том, что scala позволяет использовать" импорт", вложенный в класс, объект или признак (а не только на корневом уровне):

Пример со scala.коллекция.изменчивый.Карта и скала.коллекция.неизменный.Map (скажем, мы хотим использовать неизменяемую версию Map в тесте и изменяемую в производстве)

scala> trait Import1 {
     | import scala.collection.mutable.{Map => iMap}
     | def Test = iMap(1 -> "a")
     | }
defined trait Import1

scala> trait Import2 {
     | import scala.collection.immutable.{Map => iMap}
     | def Test = iMap(1 -> "a")
     | }
defined trait Import2

Теперь вы можете сделать:

scala> object ProductionThing extends Import1
defined module ProductionThing

scala> ProductionThing.Test
res6: scala.collection.mutable.Map[Int,java.lang.String] = Map(1 -> a)

scala> object TestingThing extends Import2
defined module TestingThing

scala> TestingThing.Test
res7: scala.collection.immutable.Map[Int,java.lang.String] = Map(1 -> a)

Или вы можете использовать тот же механизм для масштабирования импорта внутри класса и внедрения этого класса в SomeBusinessObject.