【问题标题】:Dependency injection without classes Scala没有类Scala的依赖注入
【发布时间】:2021-04-22 08:38:23
【问题描述】:

我喜欢编写没有类的 Scala 代码,只使用函数和对象。

例如

object Something {
  def foo() = {
    SomeDependency().doIt()
    ...
  }
}

object SomethingElse {
  def baz = {
    val x = Something.foo()
    ...
  }
}

但是,我遇到了无法测试该代码的问题,因为我无法模拟任何内容。我必须重构代码并让它接受一个参数,然后必须不必要地实例化类。

class Something(someDependency: SomeDependency) {
  def foo() = {
    someDependency.doIt()
    ...
  }
}

class SomethingElse(something: Something) {
  def baz = {
    val s = new SomeDependency()
    val x = new Something(s).foo()
    ...
  }
}

我有时会使用隐式,但它会变得很麻烦,因为您需要将它添加到每个方法中。

object Something {
  def foo()(implicit someDependency: SomeDependency) = {
    someDependency().doIt()
    ...
  }
}

object SomethingElse {
  def baz(implicit something: Something) = {
    val x = something.foo()
    ...
  }
}

在 Python/JS 等其他语言中,您可以直接模拟依赖项,而不是让您的类接受依赖项。有什么办法可以解决这个问题,或者只是在没有类的情况下编写 scala 的反模式。

【问题讨论】:

  • 你不能吃你的蛋糕。如果您不想在方法中添加参数,那么您必须将测试限制为验证返回值。
  • 关于是否需要为每个方法添加隐式参数,请参阅stackoverflow.com/questions/64267742/…stackoverflow.com/questions/59175012/…
  • 请不要破坏您的帖子。通过在 Stack Exchange 网络上发帖,您已在 CC BY-SA 4.0 license 下授予 Stack Exchange 分发该内容的不可撤销的权利(即无论您未来的选择如何)。根据 Stack Exchange 政策,帖子的非破坏版本是分发的版本,因此,任何破坏行为都将被撤销。如果您想了解更多关于删除帖子的信息,请参阅:How does deleting work?

标签: scala dependency-injection implicit


【解决方案1】:

尽管能够在 Scala 中以命令方式工作,但 Scala 是为函数式编程而设计的。您需要模拟事物这一事实意味着您的函数具有副作用,因此,它们不是纯函数,因此它不是函数式编程。

Scala 中有模拟框架,但它们不允许您像 Python 那样覆盖函数的功能。

你也可以使用高阶函数来传递依赖,像这样:

object Something {
  def foo(someDependencyFunction: A => B): C = {
    someDependencyFunction(...)
    ...
  }
}

object SomethingElse {
  def bar(SomethingFoo: (A => B) => C)(someDependencyFunction: A => B): D = {
    SomethingFoo(someDependencyFunction)
      ...
  }
}

但我真的不明白避免类的意义,也许如果你解释为什么你不想使用类,有人可以在解决方案上提供更好的帮助

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-12-29
    • 1970-01-01
    • 2019-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-16
    相关资源
    最近更新 更多