2016-11-21 33 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 ... 
     } 
    } 
    } 
}