【发布时间】:2013-04-03 14:34:14
【问题描述】:
我的应用程序使用一个属性文件来加载多个属性。
应用程序的每个实例都有 3 个与环境相关的参数 - 其中一个是属性,另外两个是基于它计算的。
class Environment(val properties: Properties) {
val dbUrl = valueOrError("db.url")
val host = valueOrError("host")
//...
val environmentFlag = valueOrError("env.flag")
val environmentToken = environmentFlag match {
case "live" => "L"
case "staging" => "S"
case "test" => "T"
val environmentUrlPrefix = environmentFlag match {
case "live" => ""
case "staging" => "staging-"
case "test" => "test"
}
}
在我看来,这 3 个 environment* 属性应该以某种方式封装。
我将所寻求的抽象称为 Discriminator,因为它用于区分 3 种(目前)环境类型。由于在一个正在运行的应用程序中,只有一组这样的 environment* 属性,因此我将其实现为 object:
class Environment(val properties: Properties) {
val dbUrl ...
object Discriminator {
val flag = valueOrError("env.flag")
val token = flag match {
case "live" => "L"
case "staging" => "S"
case "test" => "T"
val urlPrefix = flag match {
case "live" => ""
case "staging"=> "staging-"
case "test" => "test-"
}
}
}
我可以致电:environment.Discriminator.urlPrefix,这很好,但我该如何改进代码?如何摆脱重复的match?
现在感觉live 的token 和urlPrefix 的值应该一起存在(staging 的值也应该这样)——有点像作为鉴别器类的一个实例的一部分。
abstract class Discriminator(val flag = valueOrError("env.flag"),
val token: String
val urlPrefix: String)
由于我仍然想使用environment.Discriminator.urlPrefix,我仍然需要Discriminator(现在)伴生对象。
但我被困在这里 - 我不知道如何结合这些概念。
显然,我必须根据具体的 flag 字段为自己创建 3 个鉴别器实例,但是如何创建?如何调用构造函数 - 根据第一个参数(所有实例共有)传递最后两个参数?
一旦我有了这个,如何将三个实例与鉴别器伴生对象连接起来,以便我可以使用environment.Discriminator.urlPrefix?
【问题讨论】:
标签: oop scala encapsulation code-duplication companion-object