Wil*_*urn 6 dependency-injection scala
我已多次阅读这篇文章:
http://jonasboner.com/2008/10/06/real-world-scala-dependency-injection-di.html
我想我明白了.然而,有一些我不太了解的东西.
看看他的UserService示例,我看到他设置了UserRepositoryComponent来封装UserRepository.但我不明白的是UserRepositoryComponent扮演两个角色的原因:它封装了UserRepository,还提供了对UserRepository对象的引用.
我试图想象如果我想创建依赖于两个 UserRepository实例的服务,我将如何使用此模式.也许新服务的工作是将用户从"源"UserRepository复制到"目标"UserRepository.所以我想象的是这样的:
trait CopyUserServiceComponent {
val source: UserRepositoryComponent
val destination: UserRepositoryComponent
class CopyUserServiceComponent {
...
}
}
Run Code Online (Sandbox Code Playgroud)
但这与原始模式不同.在这种情况下,我在组件本身中定义依赖项,而不是从其他组件继承它们.但在我看来,这是正确的方法:组件应该声明它们的依赖关系,而不是它们包含的服务的实例.
我在这里错过了什么?
在本例中,我在组件本身中定义依赖项,而不是从其他组件继承它们。
蛋糕模式不使用继承来声明依赖关系。你看到任何“扩展”了吗UserServiceComponent
?
但在我看来,这是正确的方法:组件应该声明它们的依赖项,而不是它们包含的服务的实例。
但这正是蛋糕模式的作用:声明依赖关系!也许如果这个例子包含def userRepositoryFactory = new UserRepository
而不是val userRepository = new UserRepository
,那就更清楚了?
那么,让我们回到你的例子:
trait CopyUserServiceComponent {
val source: UserRepositoryComponent
val destination: UserRepositoryComponent
class CopyUserServiceComponent {
...
}
}
Run Code Online (Sandbox Code Playgroud)
让我们看看我们不能用它做的事情:
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
...
}
Run Code Online (Sandbox Code Playgroud)
另一方面...
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()
...
}
Run Code Online (Sandbox Code Playgroud)
编辑
为了补充答案,让我们考虑两种不同的需求:
UserRepository
.在这种情况下,您在错误的级别应用了该模式。在 Jonas 的示例中,UserRepository
处于工厂提供单例的级别。
所以,在这种情况下,你不会做UserRepository
andUserRepositoryComponent
但是,说,UserRepositoryFactory
and UserRepositoryFactoryComponent
。
UserRepository
。在这种情况下,只需执行以下操作:
trait UserRepositoryComponent {
val sourceUserService: UserService
val destinationUserService: UserService
class UserService ...
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
614 次 |
最近记录: |