将相关字段封装到伴随对象/类中,避免重复

时间:2013-04-03 14:34:15

标签: oop scala encapsulation code-duplication companion-object

我的应用程序使用属性文件来加载多个属性。

应用程序的每个实例都有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环境*属性应该以某种方式封装。

我调用了所需的抽象Discriminator,因为它用于区分3种(现在的)环境类型。由于在一个正在运行的应用程序中,只有一组这样的环境*属性,我将其实现为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
现在感觉token的{​​{1}}和urlPrefix的值应该一起生活(就像live的那些等等) - 有点像一个实例的一部分鉴别家阶级。

staging

由于我仍然想使用abstract class Discriminator(val flag = valueOrError("env.flag"), val token: String val urlPrefix: String) ,我仍然需要environment.Discriminator.urlPrefix(现在)的伴侣对象。

但我被困在这里 - 我不知道如何结合这些概念。

我显然必须根据具体的Discriminator字段创建3个Discriminator实例,但是如何?如何调用构造函数 - 根据第一个参数传递最后两个参数(这对所有实例都是通用的)?

一旦我有了这个,我如何将三个实例与Discriminator伴侣对象连接起来,以便我可以使用flag

2 个答案:

答案 0 :(得分:2)

您可以同时初始化tokenurlPrefix

val (token, urlPrefix) = flag match {
  case "live" => ("L", "")
  case "staging" => ("S", "staging-")
  case "test" => ("T", "test-")
}

答案 1 :(得分:1)

为什么不替换它:

   val token = flag match {
        case "live" => "L"
        ....
    val urlPrefix = flag match {
        case "live" => ""
        .....

有什么东西回归元组? e.g。

   val tokens = flag match {
        case "live" => ("L", "")