インターネット上で見つけたCakeのパターンに関するすべての記事で、単一レベルの依存関係がわかりました。実装とcakeパターンの混在の重複を回避する方法
しかし、私がそれを使い始めたとき、私は高レベルのクラスでしかサービスを使用できないという問題に直面し、複数の場所でそれを混在させる必要がありました。
例えば、私がサービスを持っていて、このサービスが他のサービスのセットで動作し、このセットの各サービスがデータベースを使用している場合、私はこの低レベルサービスのセットからデータベースに直接アクセスしませんでした。私は高レベルのサービスでのみすべてのデータベースクエリを作った。 しかし、場合によっては困難です。
は質問が例とより明確になることがある:
trait DatabaseServiceComponent{
val databaseService: DatabaseService
trait DatabaseService{
def getSomeData(id: Int, tableName: String): List[String]
def getFriends(id: Int): List[Int]
}
}
trait DatabaseServiceComponentImpl extends DatabaseServiceComponent{
val databaseService: DatabaseService = new DatabaseServiceImpl
class DatabaseServiceImpl extends DatabaseService{
def getSomeData(id: Int, tableName: String): List[String] = ???
def getFriends(id: Int): List[Int] = ???
}
}
trait Scoring { this: DatabaseServiceComponent =>
def importantValues: Set[String]
val tableName: String
def getScore(id: Int): Double = databaseService.getSomeData(id, tableName).count(importantValues)
}
class Scoring1 extends Scoring{this: DatabaseServiceComponent =>
val tableName: String = "s1"
override def importantValues: Set[String] = Set("a", "b")
}
class Scoring2 extends Scoring{this: DatabaseServiceComponent =>
val tableName: String = "s2"
override def importantValues: Set[String] = Set("foo", "bar")
}
class Scoring3 extends Scoring{this: DatabaseServiceComponent =>
val tableName: String = "s3"
override def importantValues: Set[String] = Set("1", "2")
}
// How to implement this correctly?
trait Scoring2FriendsAverage {this: DatabaseServiceComponent =>
val scoring2: Scoring2
def getScore(id: Int):Double ={
val scores = databaseService.getFriends(id).map(scoring2.getScore)
scores.size/scores.sum
}
}
object FriendsScoringProcessor{
val scoring2Friends = new Scoring2FriendsAverage with DatabaseServiceComponentImpl{
val scoring2 = new Scoring2 with DatabaseServiceComponentImpl // I don't like that I have to mix the implementation of a service again
}
def printScores(id: Int): Unit = {
val score = scoring2Friends.getScore(id)
println(score)
}
}
私はScoringsのセットを持っており、それらのそれぞれは、データベースを使用しています。私は、データベースを使用するスコアリングの1つを使用するFriendsScoringを持っています。私は、FriendsScoringにのみデータベース実装を混在させたいと思っており、下位レベルのサービスでそれを複製しません。
低レベルサービスへの暗黙的なコンストラクタ引数を使用して実装を提供することをお勧めします。