依赖和依赖注入_对象创建

有没有想过如何在面向对象编程中有效地管理对象之间的关系?对能够构建、描述和优化这些连接的技术感到好奇吗?那么,您听说过依赖注入吗?在本介绍中,我们将深入研究依赖项注入的世界,并探讨其在管理对象依赖项中的作用。准备好揭开这个强大概念背后的秘密了吗?让我们深入了解吧!

依赖和依赖注入

在我们继续之前,了解术语“依赖性”很重要。在面向对象编程中,依赖关系是两个类之间的关系,其中一个类依赖另一个类的功能。简单来说,就是一个类依赖于另一个类。

依赖和依赖注入_依赖注入_02

在 OOP 中,依赖关系以类内实例创建的形式出现。通过这个实例,一个类可以访问另一个类的方法。这样类就变得依赖了。

现在,我们将以伪代码的形式描述依赖关系的示例。这里我们创建一个类的 Email() 实例 EmailService()

class Email is
  method sendMessage() is
    ...

class EmailService is
  Email gmail = new Email()

  method sendMessage() is
    gmail.sendMessage()


依赖注入 或 DI 是将对象创建任务转移到代码其他部分的过程。这意味着创建一个可以使用的依赖项。这允许在我们的代码中创建松散耦合。

DI 示例

在第一个片段中, EmailService 类依赖于 Email 类。有了这种依赖性,您就不能使用不同类型的 Email. 它的实例是在 内部构造的 EmailService,因此您不能使用它的不同变体。此外,您无法测试不同的 Email 实例。

为了解决这个问题,我们尝试在此代码上使用一种类型的 DI:

interface Email is
  method sendMessage()

class GmailService implements Email is
  method sendMessage() is ...
  ...

class EmailService is
  method sendMessage(Email service) is
    service.sendMessage()


现在, EmailService 依赖于接口而不是类。有两个类使用我们的 Email 接口作为模式并构建不同的实现。对象创建现在已移至其他类,并且该接口为 EmailService 提供了不同的实现。你还可以通过方法设置你想要访问的实现 sendMessage() :

EmailService gmail = new EmailService()
gmail.sendMessage(new GmailService())


但这只是冰山一角。您需要考虑不同类型的依赖项注入。

注射类型

DI 主要分为三种类型。让我们看看它们。

  • 方法(接口)注入 - 依赖项通过类可以通过接口或另一个类访问的方法传递。前面的伪代码片段是方法注入的示例。
  • Property(Setter) 注入 ——依赖项通过单独的 setter 方法传递。该注入器的实现因语言而异。下面是这个注入的伪代码的简单示例:
class EmailService is
  Email service

  method getService() is
    return service

  method setService(Email service) is
    this.service = service

class Main is
  EmailService email = new EmailService()
  email.setService(new GmailService())

  Email gmail = email.getService()
  gmail.sendMessage()

set 根据语言的不同,您可以以不同的方式使用该 方法。例如,在 Java 中,使用 Spring 注释,您可以将配置文件中的参数包含到方法中 set 。然而,这个伪代码应该尽可能简单。

  • 构造函数注入 ——依赖项是通过类构造函数提供的。这里有我们的电子邮件示例,我们可以 EmailService() 在其中使用不同的实现来构建我们的 Email()
class EmailService is
  Email email

  constructor of EmailService(Email email) is
    this.email = email

  method sendMessage() is
    email.sendMessage()

class Main is
   EmailService gmail = new EmailService(new GmailService())
   gmail.sendMessage()

为什么我们需要 DI?

DI 允许我们编写代码,其中各部分之间的相互依赖程度较低。通过DI,我们可以从对象创建过程中释放一些类,并将它们传递给可以提供这些对象的注入器。这样,一个类将对另一个类的对象创建过程一无所知。它允许您重用依赖类,而无需对对象的每个新实例进行调整。

当您需要扩展和修改代码时,这会派上用场。但是,它也可以改进您的测试过程。使用 DI,您可以提供对同一对象进行不同调整的不同实例,您可以测试代码对其的反应方式。

但是,DI 有一些缺点。这可以解决其实现的复杂性。它包括 DI 陡峭的学习曲线、过度使用 DI 带来的问题以及使用不同框架和库实现 DI 的麻烦。

结论

我们来总结一下这个话题:

  • DI的要点是放松耦合。它可以帮助您处理依赖项。
  • 通过使用 DI,您可以提高代码灵活性并简化测试过程。
  • 这是一个复杂的主题,根据场景有不同的实现。
  • 不同语言的 DI 都有其特性,这些特性可能会影响您的使用方式。

虽然依赖注入可能是一个复杂的过程,但您现在已经基本了解它是什么以及它如何工作。如果您感兴趣,还有很多关于依赖注入及其实现的内容值得探索。随意深入研究该主题并独立扩展您的知识。