2011-02-03 43 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