Ich würde gerne das Cake Pattern zum Teilen von Teilen eines Software-Systems in Komponenten verwenden, um es komplett modular zu machen, wie in this article vorgeschlagen. Im einfachsten Fall möchte ich einige ansprechende Komponenten haben, sagen wir Logging, Config, Database, Scripts usw., die sich gegenseitig nutzen könnten. Der Code könnte so aussehenScala Cake Pattern: Teilen von großen Komponenten in separate Dateien
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
}
}
Hier die Datenbank und Konfigurationskomponenten (SomeConfig
und SomeDatabase
Züge) ist steckbar und kann zu einigen anderen Implementierungen geändert werden, wenn überhaupt erforderlich ist. Ihre Implementierungen haben Zugriff auf das Objekt core
, das sowohl Datenbank als auch Konfiguration enthält, so dass die Datenbank bei Bedarf auf die Konfiguration zugreifen kann und umgekehrt.
Also die Frage ist: Wenn jemals ein Merkmal wie SomeDatabase
wird groß und passt nicht in eine einzige Datei, wie es in separate Klassen aufgeteilt mit Zugriff auf die core
Objekt? Um genauer zu sein, lassen Sie uns sagen, ich brauche, um einen Code aus connect-Methode zu bewegen in SomeDatabase
auf eine andere Datei:
// 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
ist Implementierungsdetails wie SomeDatabase Werke, so möchte ich natürlich nicht, um es ein machen Merkmal und mische es in die Anwendung. Gibt es eine Möglichkeit, Zugriff auf core
Objekt für SomeClass
bereitzustellen?
Einige verwandte Links:
- 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
Dave, danke für die Antwort. Bis jetzt scheint es der einzig vernünftige Weg zu sein. Das einzige, was ich nicht darüber schreibe, ist die Notwendigkeit, 'coreComp.' bei jedem Aufruf irgendeiner Kernmethode einzugeben. Leider scheint es keine Option zu geben, direkt mit 'CoreInterface' zu arbeiten, oder? – nab
Sie können 'coreComp._' importieren, um die Eingabe zu reduzieren. – leedm777