如何改善这种蛋糕模式的尝试

时间:2012-11-10 11:59:28

标签: scala

这是我实施Scala蛋糕模式的早期尝试之一:

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 {
.....
}

这有效,但我做得对吗?

1 个答案:

答案 0 :(得分:3)

DbConfig摘要变为抽象并使用def since,可以使用defval来覆盖lazy val,但不是相反。

SillySystem is not a DbConfig,所以使用依赖注入而不是继承。

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