2016-11-21 64 views
1

我們使用蛋糕模式來抽象具有自我類型註釋的組件(數據庫,模擬),這是注入頂級調用。斯卡拉案例類豐富了抽象組件(蛋糕模式)

在一個案例類中,我們希望通過擴展共同特徵來豐富它的行爲。但是如果我們想讓這個case類調用一個抽象組件,怎麼做呢? 將案例類重構爲抽象將刪除所有應用,不應用,複製......的實現我們需要做數據庫和模型之間的映射(例如使用Slick)。

這裏是代表植物分割成數塊作爲資源由帳戶擁有的爲例:

trait Resource { 
    def getAccount: Future[Account] 
} 

case class Account(id: Int) 

case class Block(id: Int, name:String, accountId: Int) extends Resource 

case class Plant(id: Int, name: String, blockId: Int) extends Resource { 
    this: PlantDBComponent => 

override def getAccount: Future[Account] = plantDB.getAccount(this) 

} 

trait PlantDBComponent { 
    def plantDB: PlantDB 

    trait PlantDB { 
    def getAccount(plant: Plant): Future[Account] 
    } 
} 

trait SlickPlantDBComponent { 
    def blockDB = SlickPlantDB() 

    trait SlickPlantDB extends PlantDB { 
    def getAccount(block: Block): Future[Account] = { 
     val q = for { 
     block <- BlockTable if block.id === plant.blockId 
     account <- AccountTable if account.id === block.accountId 
     } yield account 

     db.run(q.result.head) 
    } 
    } 
} 

如何做沒有重新實現所有的情況下,類樣板任何想法?在具有案例類模式匹配的資源伴隨對象中添加getAccount不會解決問題

+0

給我看在你想達到 – pamu

+0

爲什麼你想什麼代碼'Account'一個'Resource'? – pamu

+0

添加更具體的代碼示例。資源是一種通用特徵,旨在用於權限訪問。用戶(此處未顯示)屬於一個帳戶,並且如果用戶屬於具有getAccount方法的資源相同的帳戶,我們要檢查所有類型的資源(塊,工廠,...) – mlardeur

回答

0

我們選擇實施一個ResourceService,根據資源類型返回資源所屬的帳戶。

這裏是特質成分:

trait ResourceServiceComponent { 

    val resourceService: ResourceService 

    trait ResourceService { 
    def getAccount(resource: Resource): Future[Account] = { 
     resource match { 
     case plant: Plant => blockDB.getAccount(plant.blockId) 
     case ... 
     } 
    } 
    } 
}