【发布时间】:2012-06-30 12:07:18
【问题描述】:
如何在 Scala 中创建功能正常的可配置对象?我在Reader monad 上观看了 Tony Morris 的视频,但我仍然无法将这些点联系起来。
我有一个硬编码的Client 对象列表:
class Client(name : String, age : Int){ /* etc */}
object Client{
//Horrible!
val clients = List(Client("Bob", 20), Client("Cindy", 30))
}
我希望在运行时确定Client.clients,可以灵活地从属性文件或数据库中读取它。在 Java 世界中,我会定义一个接口,实现两种类型的源,并使用 DI 分配一个类变量:
trait ConfigSource {
def clients : List[Client]
}
object ConfigFileSource extends ConfigSource {
override def clients = buildClientsFromProperties(Properties("clients.properties"))
//...etc, read properties files
}
object DatabaseSource extends ConfigSource { /* etc */ }
object Client {
@Resource("configuration_source")
private var config : ConfigSource = _ //Inject it at runtime
val clients = config.clients
}
这对我来说似乎是一个非常干净的解决方案(代码不多,意图明确),但是 var 确实跳出来了(OTOH,在我看来不是 真的很麻烦,因为我知道它会一次性注入)。
Reader monad 在这种情况下会是什么样子,像我 5 岁一样向我解释它,它有什么优势?
【问题讨论】:
-
vals 可以使用反射进行修改,因此您的依赖注入库可能会“注入 val” -
@gerferra 如果我们有 var,那么通过反射修改 val 的意义何在?
-
为什么不让
Client成为一个带参数的类,这样配置就可以传递给Client的实例? -
@matt 对,这将是另一种方法,但这仍然让我不清楚是否/为什么首选
Readermonad。 -
您可能会发现Rúnar's NEScala talk 的前半部分更平易近人。
标签: scala configuration monads reader-monad