首先,你应该解耦UserServiceComponent
从实施UserService
:
trait UserService extends RepositoryDelegator[User] {
def getPublicProfile(id: String): Either[Error, User]
}
trait UserServiceComponent {
val userService: UserService
}
trait DefaultUserServiceComponent extends UserServiceComponent { self: UserRepositoryComponent =>
protected class DefaultUserService extends UserService {
def getPublicProfile(id: String): Either[Error, User] = userRepository.getPublicProfile(id)
}
val userService: UserService = new DefaultUserService
}
trait AlternativeUserServiceComponent extends UserServiceComponent {
protected class AlternativeUserService extends UserService {
def getPublicProfile(id: String): Either[Error, User] = call webservice here for exemple...
}
val userService: UserService = new AlternativeUserService
}
如果这看起来很冗长,那么确实如此。蛋糕的图案不是特别简洁。
但请注意它如何解决您的依赖问题UserRepositoryComponent
即使实际上并不需要(例如仅使用AlternativeUserService
).
现在,在实例化应用程序时我们所要做的就是混合DefaultUserServiceComponent
or AlternativeUserServiceComponent
.
如果您碰巧需要访问这两个实现,则确实应该公开两个 userService 值名称。其实有3个名字,比如:
- 默认用户服务
DefaultUserService
执行
- 替代用户服务
AlternativeUserService
执行
- mainUserService 适用于任何
UserService
实现(应用程序在“混合时间”选择哪一个)。
举例来说:
trait UserService extends RepositoryDelegator[User] {
def getPublicProfile(id: String): Either[Error, User]
}
trait MainUserServiceComponent {
val mainUserService: UserService
}
trait DefaultUserServiceComponent { self: UserRepositoryComponent =>
protected class DefaultUserService extends UserService {
def getPublicProfile(id: String): Either[Error, User] = userRepository.getPublicProfile(id)
}
val defaultUserService: UserService = new DefaultUserService
}
trait AlternativeUserServiceComponent {
protected class AlternativeUserService extends UserService {
def getPublicProfile(id: String): Either[Error, User] = ??? // call webservice here for exemple...
}
val alternativeUserService: UserService = new AlternativeUserService
}
然后你可以像这样实例化你的蛋糕:
object MyApp
extends MainUserServiceComponent
with DefaultUserServiceComponent
with AlternativeUserServiceComponent
with MyUserRepositoryComponent // Replace with your real UserRepositoryComponent here
{
//val userService = defaultUserService
val mainUserService = alternativeUserService
}
在上面的例子中,明确想要访问的服务DefaultUserService
会放DefaultUserServiceComponent
作为其组件的依赖项(同样适用于AlternativeUserService
and AlternativeUserServiceComponent
),以及刚需要的服务some UserService
而是会放MainUserServiceComponent
作为依赖。您在“混合时间”决定哪种服务mainUserService
指向(这里,它指向DefaultUserService
执行。