scala – Cake模式:每个实现一个组件,或每个特性一个组件?
我正在努力在我的应用程序上使用蛋糕模式.
在网上找到的例子中,例子是基本的,但不涉及更复杂的需求.我想做的事情并不那么花哨:我想在蛋糕模式应用程序中使用相同类型的2个服务,使用不同的实现. trait UserServiceComponent { self: UserRepositoryComponent => val userService: UserService class DefaultUserService extends UserService { def getPublicProfile(id: String): Either[Error,User] = userRepository.getPublicProfile(id) } class AlternativeUserService extends UserService { def getPublicProfile(id: String): Either[Error,User] = call webservice here for exemple... } } trait UserService extends RepositoryDelegator[User] { def getPublicProfile(id: String): Either[Error,User] } 如果我一次使用UserService的一个实现,它工作正常,但如果我在同一时间需要两个实现,我真的不知道如何做到这一点. 我应该创建2个不同的组件吗?每一个都暴露出不同的userService值名称? (defaultUserService / alternativeUserService).使用一个组件进行实现我不知道其他组件在使用名称userService时如何能够知道使用了哪个实现,因为我的应用程序中有2个不同的实现. 顺便说一下,当组件表达对UserRepositoryComponent的依赖时,虽然并非所有实现都需要它,但我觉得只有一个组件对吗有点奇怪? 有人可以给我一些建议,以便我知道该怎么做? 一种相关的问题: 谢谢 解决方法
首先,您应该将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或AlternativeUserServiceComponent. 如果您碰巧需要访问这两个实现,那么您确实应该公开两个userService值名称.事实上,3个名字,如: > DefaultUserService实现的defaultUserService 举例: 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和AlternativeUserServiceComponent也是如此),而只需要一些UserService的服务会将MainUserServiceComponent作为依赖项.您决定“混合时间”服务mainUserService指向哪个(这里,它指向DefaultUserService实现. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |