2011-02-03 76 views
1

我在写几个地方部署的系统,每个站点都需要自己的配置和设置。 “配置”是特定站点所需的命名值(例如,数据库URL,S3存储桶名称);每个配置都是必需的,通常不会有默认配置,而且通常是字符串值。设置是一个命名值,但它只是调整系统的行为;它通常是数字或布尔值,通常有一些默认值。如何实现配置和设置?

到目前为止,我一直在使用属性文件或类似的东西,但这是一个可怕的解决方案。有几次,开发人员添加了配置需求,但没有将该值添加到实时配置文件中,因此新版本通过了所有测试,然后在发布时就失败了。

当然,对于要编译的每个文件来说更好 - 因此,如果缺少配置或错误类型,它将无法通过编译器 - 并将特定于站点的类注入到构建中每个站点。作为一个骨骼,一个Scala文件可以很容易地建模更复杂的值,特别是列表,还有映射和元组。

不足之处在于,这些文件有时由不是开发人员的人维护,所以它必须非常明了,这是属性文件的优势。 (有人向我解释XML配置:可编译文件的所有复杂性,但是属性文件的运行时风险。)

我正在寻找的是一种用于定义组所需名称和允许值的简单模式。有什么建议么?

+0

我不明白为什么你的q uestion是scala特有的。我错过了一个重要的观点吗? – Nicolas 2011-02-03 15:32:27

回答

0

虽然Lift本质上是一个Web框架,但它也有一些实用工具。其中之一是依赖注入,请参阅:http://simply.liftweb.net/index-8.2.html#toc-Section-8.2。因此,您可以创建一个基于trait的默认值,然后对Runtime,Development,Test ...环境值进行子类化。我认为对于没有scala知识的人来说,把一些override def defaultValue = "new value"放在一个文件中很容易。

1

如何使用Mixin组合物?由于性状从右适用于左,我们可以:

定义性状:

默认属性:

trait PropertyA { 
    val userName = "default" 
    def useUserName() : Unit = { 
    println(userName) 
    } 
} 

一些其他财产:

trait SomePropertyA extends PropertyA { 
    val userName = "non-default" 
    def useUserName() : Unit = { 
    println(userName) 
    } 
} 

定义默认属性的抽象类:

trait HasPropertyA { 
    val prop : PropertyA = new PropertyA 
}

定义与非抽象类 - 默认属性:

trait HasSomeOtherPropertyA extends HasPropertyA { 
     override val prop:PropertyA = new SomePropertyA {} 
}

在你的类使用默认的:

trait MyClass extends PropertyA { 
    doSomethingWith(prop.userName) 
}

或在其他情况与其他一些财产混用:

if(env.isSome) { 
    val otherProps = MyClass with HasSomeOtherPropertyA 
    doSomethingWith(prop.userName)// userName == non-default! 
} 

在文中详细阅读Scalable Component Abstractions