Spring中依赖注入和工厂模式的区别
依赖注入和工厂模式在某种意义上几乎是相似的,它们都遵循接口驱动的编程方法并创建类的实例。
工厂模式
在工厂模式中 ,客户端类仍然负责按类获取产品的实例 getInstance() 方法,这意味着客户端类直接与工厂类耦合,没有工厂类就不能进行单元测试。
实现: 在本例中,我们将在ExpenseTracker应用程序的帮助下分析工厂模式和DI之间的区别。在这个应用程序中,我们有一个依赖类ExpenseTracker,它依赖于ExpenseCalculator类。这里我们将同时使用工厂模式和依赖注入来理解它们之间的区别。
示例:
// 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);
}
}
代码解释: 在上面的例子中,我们可以看到我们的从属类 ExpenseTracker 直接与 ExpenseCalculatorFactory 因为它正在调用静态 getInstance() method of ExpenseCalculatorFactory 类,以满足其依赖性。如果我们想测试ExpenseTracker类,我们必须有ExpenseCalculatorFactory类,它不适合用于ExpenseTracker类的单元测试,从而增加了单元测试的难度。
另一方面,如果我们将使用依赖注入,那么依赖将由Spring框架或依赖注入容器添加,因为我们颠倒了依赖获取的责任。这将使IOC容器负责注入依赖项,而不是依赖类,它将把任何客户机或依赖类的外观转换为POJO类。
依赖注入
在依赖注入(DI)的情况下,客户端不知道依赖是如何创建和管理的。客户机类只知道依赖项,并且大多数依赖项都是由IOC容器注入的。例如,Bean类不存在任何硬编码的依赖,它们是由IOC容器(如Spring Framework)注入的。
示例:
// 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依赖注入。
依赖注入和工厂模式的区别
依赖注入 | 工厂模式 |
---|---|
DI只知道依赖关系。它不知道关于集装箱和工厂的任何事情。 | 它增加了对象、工厂和依赖关系之间的耦合。它需要一个依赖对象和一个工厂对象才能正常工作。 |
DI使单元测试更容易。它不需要样板代码。 | 工厂模式需要您想要测试的对象、工厂对象和依赖对象。 |
DI比工厂模式更灵活。它还提供了切换不同DI框架的功能,如Spring IOC和谷歌Guice。 | 它没有依赖注入那么灵活。 |
DI需要一个容器和配置来注入依赖项。 | 工厂模式不需要这些配置步骤。 |
由于耦合更少,DI的结果更清晰。客户端类看起来像POJO类。 | 在工厂模式的情况下,客户端类不像DI中那样干净。 |