DI在Scala与蛋糕模式
这个
article通过Scala的Cake Pattern解释了依赖注入.
我对这种模式的好处的理解是,特征可以与(生产对测试)混合使用静态检查. 在Bonér先生的例子中,他列出了这个完成的(每个例子)代码: UserRepositoryComponent和UserServiceComponent 我根据我的理解添加了评论. trait UserRepositoryComponent { val userRepository: UserRepository // stand-alone component class UserRepository { ... // actual implementation here } } trait UserServiceComponent { this: UserRepositoryComponent => //Requires a mixed-in UserRepo*Component val userService: UserService class UserService { ... // actual implementation here } } 我的理解是服务依赖于注入存储库组件. 出于生产目的,可以使用以下内容将“生产”存储库组件连接到UserServiceComponent: object ComponentRegistry extends UserServiceComponent with UserRepositoryComponent { val userRepository = new UserRepository val userService = new UserService } 如果我们的生产代码想要使用userRepository或userService,那么通过简单导入使用它们的正确方法是什么? 到目前为止,我认为我理解文章的一半,但我不确定如何使用ComponentRegistry对象. 解决方法
你是第一次进入厄运兄弟的面包店:
What are some compelling use cases for dependent method types? 要回答你的问题,使用userService的正确方法是使用另一个特性并将其搞砸: trait Example { this: UserServiceComponent => def getExampleUser() = userService.getUser("ExampleUser") } 现在无论这个新特性做什么都没有直接耦合到像ComponentRegistry这样的对象.相反,您的应用程序变为: object Application extends Example with UserServiceComponent with UserRepositoryComponent { val userRepository = new UserRepository val userService = new UserService } 无论如何,你应该跑到山上,因为如果你真的想要使用蛋糕,你应该做更像这样的事情: trait UserRepositoryComponent { type UserRepository <: UserRepositoryLike val userRepository: UserRepository trait UserRepositoryLike { def getUserOrSomething() } } trait UserRepositoryComponentImpl extends UserRepositoryComponent { type UserRepository = UserRepositoryImpl val userRepository = new UserRepositoryImpl class UserRepositoryImpl extends UserRepositoryLike { override def getUserOrSomething() = ??? } } trait UserServiceComponent { this: UserRepositoryComponent => type UserService <: UserServiceLike val userService: UserService trait UserServiceLike { def getUserNameById(id: Int): String } } trait UserServiceComponentImpl extends UserServiceComponent { this: UserRepositoryComponent => type UserService = UserServiceImpl val userService = new UserServiceImpl class UserServiceImpl extends UserServiceLike { override def getUserNameById(id: Int) = userRepository.getUserOrSomething } } trait Example { this: UserServiceComponent => def getExampleUser() = userService.getUserNameById(1) } object Application extends Example with UserRepositoryComponentImpl with UserServiceComponentImpl 现在节省一些时间,丢弃蛋糕模式,并做一些事情simple. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |