我想使用一些軟件系統的分割部分的蛋糕圖案成組件,使其完全模塊化爲this article建議。在最簡單的情況下,我想有一些可嘲弄的組件,比如說可能潛在使用對方的日誌記錄,配置,數據庫,腳本等。該代碼可能看起來像斯卡拉蛋糕圖案:拆分大型部件到單獨的文件
trait AbstractConfig {
def config: AbstractConfigInterface
trait AbstractConfigInterface {
def test: Unit
}
}
trait SomeConfig extends AbstractConfig {
this: Core =>
def config = SomeConfigImplementation
object SomeConfigImplementation extends AbstractConfigInterface {
def test = println("conf.test method called")
}
}
trait AbstractDatabase {
def database: AbstractDatabaseInterface
trait AbstractDatabaseInterface {
def connect: Unit
}
}
trait SomeDatabase extends AbstractDatabase {
this: Core =>
def database = SomeDatabaseImplementation
object SomeDatabaseImplementation extends AbstractDatabaseInterface {
def connect = {
println("connect method called")
core.conf.test
}
}
}
trait Core {
this: AbstractDatabase with AbstractConfig =>
def core = CoreInterface
object CoreInterface {
def db = database
def conf = config
}
}
object app extends Core with SomeDatabase with SomeConfig
object Run {
def main(args: Array[String]) = {
app.core.db.connect
}
}
這裏的數據庫,並配置組件(SomeConfig
和SomeDatabase
特點)都是可插拔的,在需要時可以改變一些其他實現。它們的實現可以訪問保存數據庫和配置的對象core
,因此數據庫可以根據需要訪問配置,反之亦然。
所以現在的問題是:如果真像SomeDatabase
一些特質變大,不適合到一個單一的文件如何將其拆分成獨立的類固定接入core
對象?更具體地講,比方說我需要在SomeDatabase
移動一些代碼OUT連接方法的另一個文件:
// SomeDatabase.scala
trait SomeDatabase extends AbstractDatabase {
this: Core =>
def database = SomeDatabaseImplementation
object SomeDatabaseImplementation extends AbstractDatabaseInterface {
def connect = {
val obj = new SomeClass()
}
}
}
// SomeClass.scala in the same package
class SomeClass {
core.conf.test // Does not compile - how to make it work??
}
SomeClass
是如何SomeDatabase工作的實施細則,所以我顯然不希望使之成爲特質並將其混合到應用程序中。有沒有什麼辦法可以爲SomeClass
提供訪問core
對象?
一些相關鏈接:
- Dependency Injection vs Cake Pattern by Jan Machacek
- Real World Scala: Dependency Injection by Jonas Boner
- Dependency Injection in Scala: Extending the Cake Pattern by Adam Warsky
- Scalable Component Abstractions by Martin Odersky & Matthias Zenger
戴夫,感謝您的回答。到目前爲止,這似乎是唯一合理的方法。唯一不關心的是在任何核心方法的每次調用中輸入'coreComp.'的必要性。不幸的是,似乎沒有直接使用'CoreInterface'的選項,是嗎? – nab 2012-04-23 08:06:59
您可以'輸入coreComp._'來減少輸入。 – leedm777 2012-04-23 14:25:45