2017-06-16 54 views
0

在Internet上發現的所有與Cake patter相關的文章中,我都看到了單個級別的依賴關係,這對我來說很清楚。如何避免重複執行與蛋糕模式的混合

但是當我開始使用它時,我遇到了一個問題,我不能僅在高級別類中使用服務,而且我需要將它混合到多個位置。

例如,如果我有一個服務,並且此服務與其他一組服務一起工作,並且此組中的每個服務都使用一個數據庫,我嘗試不直接訪問來自這組低級服務的數據庫。我僅在高級服務中完成所有數據庫查詢。 但在某些情況下很困難。

可能問題會隨着這個例子更清楚:

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) 
    } 

} 

我有一組刻劃和他們每個人使用的數據庫。我有一個使用數據庫評分的FriendsScoring。我希望能夠將數據庫實現僅混合到FriendsScoring,並且不要在較低級別的服務中複製它。

我看到一個很好的(可能)解決方案是通過隱式構造函數參數向低級別服務提供實現。

回答

2

它看起來像蛋糕模式組件和服務的混合水平。

如果我們在服務層使用Scoring,那麼它不應該出現在蛋糕模式層面。

您可能需要像你這樣的數據庫,以Scoring分成兩個嵌套的特質在每個級別:

trait ScoringComponent {this: DatabaseServiceComponent => 

    trait ScoringService { 
    def getScore(id: Int): Double = 
     databaseService.getSomeData(id, tableName). 
     count(importantValues) 
    } 
} 

然後你就可以混合所需要的依賴後使用ScoringService