В этом случае я определяю зависимости в самом компоненте, а не наследую их от какого-то другого компонента.
Шаблон торт не использует наследование для объявления зависимостей.Вы видели какое-либо «расширение» в UserServiceComponent
?
Но мне кажется, что это правильный путь: компоненты должны объявлять свои зависимости, а не экземпляры включенных ими служб.
Но это именно то, что делает шаблон торта: объявлять зависимости!Возможно, если бы пример содержал def userRepositoryFactory = new UserRepository
вместо val userRepository = new UserRepository
, это было бы более понятно?
Итак, давайте вернемся к вашему примеру:
trait CopyUserServiceComponent {
val source: UserRepositoryComponent
val destination: UserRepositoryComponent
class CopyUserServiceComponent {
...
}
}
Давайте посмотрим, что мы не может сделать с этим:
trait CopyUserServiceComponent {
// The module will need to see my internals!
private val source: UserRepositoryComponent
private val destination: UserRepositoryComponent
class CopyUserServiceComponent {
...
}
}
trait CopyBigUserServiceComponent extends CopyServiceComponent {
// Any change in implementation will have to be reflected in the module!
val tmp: UserRepositoryComponent
...
}
С другой стороны ...
trait UserRepositoryComponent {
val userRepositoryFactory: () => UserRepository
class UserRepository {
...
}
}
trait CopyUserServiceComponent {
self: UserRepositoryComponent =>
// No problem here
private val source: UserRepository = userRepositoryFactory()
private val destination: UserRepository = userRepositoryFactory()
class CopyUserServiceComponent {
...
}
}
trait CopyBigUserServiceComponent extends CopyServiceComponent {
self: UserRepositoryComponent =>
// No problem here either
val tmp: : UserRepository = userRepositoryFactory()
...
}
РЕДАКТИРОВАТЬ
В дополнение к ответу давайте рассмотрим две разные потребности:
- Мне нужно много экземпляров
UserRepository
.
В этом случае вы применяете шаблон неправильноуровень.В примере с Джонасом UserRepository
находится на уровне фабричного синглтона.
Таким образом, в этом случае вы бы не делали UserRepository
и UserRepositoryComponent
, но, скажем, UserRepositoryFactory
и UserRepositoryFactoryComponent
.
- Мне нужно ровно два синглтона
UserRepository
.
В этом случае просто сделайте что-то вроде этого:
trait UserRepositoryComponent {
val sourceUserService: UserService
val destinationUserService: UserService
class UserService ...
}