我想使用 Cake Pattern 将某些软件系统的部分拆分为组件,以使其完全模块化,如本文中所建议的那样。在最简单的情况下,我想要一些可模拟的组件,比如日志、配置、数据库、脚本等,它们可能会相互使用。代码可能看起来像
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
移到另一个文件中:
// 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 如何工作的实现细节,所以我显然不想让它成为一个特征并将其混合到应用程序中。有没有办法提供对core
对象的访问SomeClass
?
一些相关链接: