关于连接,您应该在完成连接后关闭它们(返回池),这与混合实现是正交的。
至于配置等,我喜欢这种方法,但它的问题是大多数时候你希望加载 config 之类的东西是单例的,但如果你只是做类似的事情
trait Configuration {
val config = loadConfig
}
class Foo with Configuration
class Bar with Configuration
val f1 = new Foo
val f2 = new Foo
val b1 = new Bar
val b2 = new Bar
然后,您最终会加载四个不同的配置副本。
解决此问题的一种方法是将loadConfig 委托给单例对象:
object Configuration {
val config = loadConfig
}
trait Configuration {
def config = Configration.config
}
这行得通,但让单元测试和覆盖功能变得更加困难(如果我希望有时从数据库加载配置怎么办?)
另一种可能是代理类:
trait Configuration {
def loadConfig: Config
lazy val config: Config = loadConfig
}
class ConfigurationProxy(cfg: Configuration) extends Configuration {
def loadConfig = cfg.config
}
object Main extends App with Configuration {
def loadConfig = ??? // executed only one per application
...
}
class Foo extends ConfigurationProxy(Main)
class Bar extends ConfigurationProxy(Main)
val f1 = new Foo
val f2 = new Foo
val b1 = new Bar
val b2 = new Bar
现在,所有四个变量都在查看同一个 Config 实例。
但是如果你有一个函数需要Configuration,你仍然可以传递其中的任何一个:
def connectToDB(cfg: Configuration) = ???
connectToDB(Main)
connectToDB(f1)
connectToDB(b2)
等等