この記事で提案されているように、一部のソフトウェアシステムの一部をコンポーネントに分割して完全にモジュール化するためにCakePatternを使用したいと思います。最も単純なケースでは、モック可能なコンポーネント、たとえば、相互に使用する可能性のあるロギング、構成、データベース、スクリプトなどが必要です。コードは次のようになります
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
オブジェクトへのアクセスを保持する個別のクラスに分割する方法はありますか?具体的には、connectメソッド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
か?
いくつかの関連リンク: