【问题标题】:Why should one inject concrete classes opposed to injecting interfaces为什么要注入具体类而不是注入接口
【发布时间】:2021-06-23 11:12:39
【问题描述】:

我目前正在开发一个 Java 项目。我对Java很陌生。我过去做过 C++/C#。

我有一个关于依赖注入的问题。我已经很清楚为什么要使用它了。

public class MyClass
{
  @Inject
  private IFoo fooInterface;

  @Inject
  private Bar barClass;
  
}

public interface iFoo
{
}

public class Bar
{
}

现在注入一个实际的接口实现来减少依赖是非常有意义的。

但是为什么我要注入一个“普通”类却没有实现接口呢?

你能帮我理解一下吗?

编辑: 谢谢你们所有的cmets。我相信我现在明白了依赖注入背后的想法。

只是为了澄清: 在与其他开发人员交谈后,我被告知在我们的项目中,所有注入的依赖项都是在启动时构建的。但是,并非所有成员对象在启动时都是已知的。因此这些成员对象不能通过构造函数传递。

还有一点是,对于每个类类型(例如Bar),整个项目只需要构建一个实例接缝,这个实例将在整个项目中传递并由多个线程。因此,如果我们使用成员变量,我们可能会遇到并发问题。

=>我们团队的结论是避免成员变量并将所有参数作为函数参数传递。

=>现在我正在寻找一种方法来拥有 DI(这非常有意义),同时也拥有成员变量。

【问题讨论】:

  • 这能回答你的问题吗? Dependency injection with interfaces or classes
  • 在您的最小示例中,它没有任何意义(但话又说回来:Bar 本身的类本身毫无意义)。但是,如果Bar 本身有一些依赖项可以被注入或者可以以不同的方式配置,那么注入它可以将Bar 的使用与必须正确配置它分离。另外:即使它不是一个接口,也有人可以编写一个扩展 BarMegaBar 并使用它来满足 Bar 依赖关系。
  • 嗯,谢谢,这是有道理的。然而,当一个 bar 实例被注入到多个类中时, bar 不能有实例成员(因为同一个实例被注入到整个项目中)。如果我不能拥有实例成员,这将不再像 OOP。我说的对吗?
  • @Avinash 不抱歉,这没有回答我的问题
  • 为什么你认为它不能有实例成员?这似乎是一个无处不在的任意限制。您是否正在考虑诸如线程安全之类的问题?因为拥有字段并不一定会使类不是线程安全的。并且被注入多个地方并不一定意味着对象必须是线程安全的。最后但并非最不重要的一点是:DI 可以配置为为每个应该注入的位置创建一个 Bar 的新实例,而依赖项仍然不需要知道这一点。再次:将“如何创建”与“如何使用”分离。

标签: java dependency-injection


【解决方案1】:

当使用依赖注入时,一个类将创建它的依赖的责任委托给依赖注入系统。所以你永远不想自己实例化一个依赖。

否则,如果您的 Bar 类需要依赖项,您也必须在 MyClass 中处理它们。如果你在很多地方使用Bar 并为其添加依赖项,你还必须更改Bar 的所有这些用法。

【讨论】:

  • 谢谢你的回答。但是(如上面的评论中所说)我的 Bar 类的实例成员呢。因为依赖注入栏不能有实例成员吧?
  • 你为什么这么认为?当然Bar可以有会员。事实上,它也可以将东西注入自身。这几乎就是 DI 的point
  • 大家好,我在上面澄清了我的问题并添加了一些项目背景信息,为什么我们尽量避免使用成员变量
猜你喜欢
  • 2017-02-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-06
  • 2013-01-13
  • 1970-01-01
  • 1970-01-01
  • 2016-08-03
相关资源
最近更新 更多