gpt4 book ai didi

scala - Jonas Bonér 的依赖注入(inject)策略似乎是有限的——但也许我不明白

转载 作者:行者123 更新时间:2023-12-04 15:15:42 25 4
gpt4 key购买 nike

我已经多次阅读这篇文章:

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 {
...
}
}

但这与原来的模式不同。在这种情况下,我在组件本身中定义依赖项,而不是从其他组件继承它们。但在我看来,这似乎是正确的做法:组件应该声明它们的依赖关系,而不是它们包含的服务的实例。

我在这里想念什么?

最佳答案

In this case I'm defining the dependencies in the component itself instead of inheriting them from some other component.



蛋糕模式不使用继承来声明依赖关系。您在 UserServiceComponent 中看到任何“扩展”吗? ?

But this seems to me to be the right way to do it: the components should declare their dependencies, not instances of their included services.



但这正是蛋糕模式所做的:声明依赖关系!如果示例包含 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处于工厂提供单例的级别。

    所以,在那种情况下,你不会做 UserRepositoryUserRepositoryComponent但是,比如说, UserRepositoryFactoryUserRepositoryFactoryComponent .
  • 我正好需要两个单例 UserRepository .

  • 在这种情况下,只需执行以下操作:
    trait UserRepositoryComponent {
    val sourceUserService: UserService
    val destinationUserService: UserService

    class UserService ...
    }

    关于scala - Jonas Bonér 的依赖注入(inject)策略似乎是有限的——但也许我不明白,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4078991/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com