Почему все используют эту форму определения:
trait UserServiceComponent {
def userService: UserService
trait UserService {
def findAll: List[User]
def save(user: User)
}
}
Вместо этого:
trait UserService {
def findAll: List[User]
def save(user: User)
}
trait UserServiceComponent {
def userService: UserService
}
Второй подход кажется более универсальным, поскольку трейт UserService не привязан к конкретному экземпляру компонента.
Что-то я пропустил?
Редактировать: под «более универсальным» я подразумеваю, что вы можете сделать что-то вроде этого (смешайте два торта с разными импликациями в один):
object Program extends App with UserServiceComponent with ProductServiceComponent {
object Cake1 extends UserServiceComponentImpl with DatabaseComponent1Impl {
}
object Cake2 extends ProductServiceComponentImpl with DatabaseComponent2Impl {
}
def userService = Cake1.userService
def productService = Cake2.productService
}
// def
trait DatabaseComponent{
}
trait UserService {
}
trait UserServiceComponent {
def userService: UserService
}
trait ProductService {
}
trait ProductServiceComponent {
def productService: ProductService
}
// impl
trait DatabaseComponent1Impl extends DatabaseComponent {
}
trait DatabaseComponent2Impl extends DatabaseComponent {
}
trait UserServiceComponentImpl extends UserServiceComponent {
self:DatabaseComponent =>
def userService = new UserService {}
}
trait ProductServiceComponentImpl extends ProductServiceComponent {
self:DatabaseComponent =>
def productService = new ProductService {}
}
Если вы определите UserService как вложенный трейт, вы получите исключение: несоответствие типов; найдено: Program.Cake1.UserService, требуется: Program.UserService