📜  Spring——依赖注入和工厂模式的区别

📅  最后修改于: 2022-05-13 01:55:52.273000             🧑  作者: Mango

Spring——依赖注入和工厂模式的区别

依赖注入和工厂模式在某种意义上几乎相似,它们都遵循接口驱动的编程方法并创建类的实例。

A. 工厂模式

Factory Pattern中,客户端类仍然负责通过工厂类的getInstance()方法获取产品的实例,这意味着客户端类与工厂类直接耦合,没有工厂类就无法进行单元测试。

实现:在这个例子中,我们将借助 ExpenseTracker 应用程序来区分工厂模式和 DI。在这个应用程序中,我们有一个依赖类 ExpenseTracker,它依赖于 ExpenseCalculator 类。在这里,我们将同时使用工厂模式和依赖注入来了解它们之间的区别。

例子:

Java
// Java Program to Illustrate Factory Pattern
 
// Dependent class
public class ExpenseTracker {
 
    // Getting instance of ExpenseCalculator class
    // using Factory class method
    private ExpenseCalculator expenseCal
        = ExpenseCalculatorFactory.getInstance();
 
    // Method
    public void add(Transaction transaction)
    {
 
        // Returns the expense amount
        // of ExpenseCalculator class
        int expense
            = expenseCal.getTransactionAmount(transaction);
        add(expense);
    }
}


Java
// Java Program to Illustrate Dependency Injection
 
// Dependent class ExpenseTracker
public class ExpenseTracker {
 
    // Class data member
    private ExpenseCalculator expenseCal;
 
    // Constructor
    // Dependencies are injected
    // using Constructor Dependency Injection
    public ExpenseTracker(
        ExpenseCalculator expenseCalculator)
    {
 
        // This keyword refers to current instance itself
        this.expenseCal = expenseCalculator;
    }
 
    // Method
    public void add(Transaction transaction)
    {
        int expense
            = expenseCal.getTransactionAmount(transaction);
        add(expense);
    }
 
    // Dependencies are injected
    // using Setter Dependency Injection
    public void setExpenseCalculator(
        ExpenseCalculator expenseCalculator)
    {
        this.expenseCal = expenseCalculator;
    }
}


代码说明:在上面的示例中,我们可以看到我们的依赖类ExpenseTracker直接与ExpenseCalculatorFactory耦合,因为它调用ExpenseCalculatorFactory类的静态getInstance()方法以满足其依赖关系。如果我们要测试 ExpenseTracker 类,就必须有 ExpenseCalculatorFactory 类,它不适合 ExpenseTracker 类的单元测试,使得单元测试更加困难。

另一方面,如果我们将使用 DI,那么依赖项是由 Spring 框架或 DI 容器添加的,因为我们颠倒了获取依赖项的职责。这将使 IOC 容器负责注入依赖项而不是依赖类,并且它将任何客户端或依赖类看起来变成 POJO 类。

B. 依赖注入

在依赖注入 (DI) 的情况下,客户端不知道如何创建和管理依赖项。客户端类只知道依赖关系,并且大部分依赖关系是由 IOC 容器注入的。例如,Bean 类的存在没有任何硬编码依赖,它们由 IOC 容器(如 Spring Framework)注入。

例子:

Java

// Java Program to Illustrate Dependency Injection
 
// Dependent class ExpenseTracker
public class ExpenseTracker {
 
    // Class data member
    private ExpenseCalculator expenseCal;
 
    // Constructor
    // Dependencies are injected
    // using Constructor Dependency Injection
    public ExpenseTracker(
        ExpenseCalculator expenseCalculator)
    {
 
        // This keyword refers to current instance itself
        this.expenseCal = expenseCalculator;
    }
 
    // Method
    public void add(Transaction transaction)
    {
        int expense
            = expenseCal.getTransactionAmount(transaction);
        add(expense);
    }
 
    // Dependencies are injected
    // using Setter Dependency Injection
    public void setExpenseCalculator(
        ExpenseCalculator expenseCalculator)
    {
        this.expenseCal = expenseCalculator;
    }
}

代码说明:我们可以看到ExpenseCalculator的依赖是使用类的构造函数注入到ExpenseTracker类中的,这叫做构造函数依赖注入。此外,我们可以使用 Setter 方法注入依赖项,我们也可以在上面的代码中看到,它称为 Setter Dependency Injection。

依赖注入和工厂模式的区别

Dependency Injection

Factory Pattern

DI is only aware of the dependencies. It does not know anything about the container or factory.It adds coupling between objects, factory, and dependency. It requires both a dependent object and a factory object to work properly.
DI makes the unit tests easier. It does not require boilerplate code.The factory pattern requires the object you want to test, the factory object, and the dependent object.
DI is more flexible than factory patterns. It also gives the facility to switch different DI frameworks such as Spring IOC and Google Guice.It is not much flexible as Dependency Injection.
DI requires a container and configuration in order to inject dependencies.The factory pattern does not require these configuration steps.
Due to less coupling, the result of DI is much cleaner. The client class looks like the POJO class.In the case of the Factory pattern, the client class is not clean as in DI.