1

这是我实现 Scala Cake Pattern 的早期尝试之一:

trait dbConfig {
  val m: Model = ???
}

trait testDB extends dbConfig {
  override val m = new Model(Database.forURL("jdbc:h2:mem:testdb", driver = "org.h2.Driver"))
  m.cleanDB
}

trait productionDB extends dbConfig {
  override val m = new Model(Database.forURL("jdbc:postgresql:silly:productionDB", driver = "org.postgresql.Driver"))
}

trait SillySystem extends HttpService with dbConfig {
....
// System logic
....
}

这将允许我在测试时像这样使用我的服务:

class TestService extends SillySystem with testDB {
.....
}

像这样用于生产:

class ProductionService extends SillySystem with productionDB {
.....
}

这行得通,但我做得对吗?

4

1 回答 1

3

DbConfig抽象和使用可能会有所帮助,def 因为可以def用 a 覆盖 avallazy val,但反过来不行。

SillySystem不是 aDbConfig,所以使用依赖注入而不是继承。

trait DbConfig {
  def m: Model // abstract
}

trait TestDB extends DbConfig {
  // you can override def with val
  val m = new Model(Database.forURL("jdbc:h2:mem:testdb", driver = "org.h2.Driver"))
  m.cleanDB
}

trait ProductionDB extends DbConfig {
  val m = new Model(Database.forURL("jdbc:postgresql:silly:productionDB", driver = "org.postgresql.Driver"))
}

trait SillySystem extends HttpService {
  this: DbConfig => // self-type. SillySystem is not a DbConfig, but it can use methods of DbConfig.
....
// System logic
....
}

val testService = new SillySystem with TestDB

val productionService = new SillySystem with ProductionDB

val wrongService1 = new SillySystem // error: trait SillySystem is abstract; cannot be instantiated
val wrongService2 = new SillySystem with DbConfig // error: object creation impossible, since method m in trait DbConfig of type => Model is not defined

val correctService = new SillySystem with DbConfig { val m = new Model(...) } // correct
于 2012-11-10T12:32:17.213 回答