引用的大多数使用依赖注入的例子,我们也可以使用工厂模式来解决。看起来当涉及到使用/设计时,依赖注入和工厂之间的区别是模糊或稀薄的。

曾经有人告诉我,你如何使用它才会有所不同!

我曾经使用StructureMap一个DI容器来解决一个问题,后来我重新设计了它来使用一个简单的工厂,并删除了对StructureMap的引用。

谁能告诉我它们之间的区别在哪里使用什么,这里的最佳实践是什么?


当前回答

IOC is a concept which is implemented by two ways. Dependency creation and dependency injection, Factory/Abstract factory are the example of dependency creation. Dependency injection is constructor, setter and interface. The core of IOC is to not depend upon the concrete classes, but define the abstract of methods(say an Interface/abstract class) and use that abstract to call method of concrete class. Like Factory pattern return the base class or interface. Similariliy dependency injection use base class/interface to set value for objects.

其他回答

在我看来,使用依赖注入更好,如果你是: 1. 将代码部署在小分区中,因为它可以很好地解耦一个大代码。 2. 可测试性是DI可以使用的情况之一,因为你可以很容易地模拟非去耦的对象。通过使用接口,您可以轻松地模拟和测试每个对象。 3.你可以同时修改程序的每一部分,而不需要编码它的另一部分,因为它是松散解耦的。

我相信DI是一种配置或即时化bean的方法。DI可以通过很多方式来实现,比如构造函数,setter-getter等等。

工厂模式只是实例化bean的另一种方式。此模式将主要用于必须使用工厂设计模式创建对象时,因为在使用此模式时,您不配置bean的属性,只实例化对象。

检查这个链接:依赖注入

我认为它们是正交的,可以一起使用。让我给你看一个我最近在工作中遇到的例子:

我们使用Java中的Spring框架进行DI。一个单例类(Parent)必须实例化另一个类(Child)的新对象,这些对象有复杂的协作者:

@Component
class Parent {
    // ...
    @Autowired
    Parent(Dep1 dep1, Dep2 dep2, ..., DepN depN) {
        this.dep1 = dep1;
        this.dep2 = dep2;
    }

    void method(int p) {
        Child c = new Child(dep1, dep2, ..., depN, p);
        // ...
    }
}

在这个例子中,Parent必须接收DepX实例,并将它们传递给Child构造函数。问题在于:

Parent对Child的了解比它应该了解的要多 母公司的合作者太多了 向Child添加依赖项需要更改Parent

这时我意识到工厂非常适合这里:

它隐藏了Child类的所有真实参数,就像Parent所看到的那样 它封装了创建子节点的知识,这些知识可以集中在DI配置中。

这是简化的Parent类和ChildFactory类:

@Component
class Parent {
    // ...
    @Autowired
    Parent(ChildFactory childFactory) {
        this.childFactory = childFactory;
    }

    void method(int p) {
        Child c = childFactory.newChild(p);
        // ...
    }
}

@Component
class ChildFactory {
    // ...
    @Autowired
    Parent(Dep1 dep1, Dep2 dep2, ..., DepN depN) {
        this.dep1 = dep1;
        this.dep2 = dep2;
        // ...
        this.depN = depN;
    }

    Child newChild(int p) {
        return new Child(dep1, dep2, ..., depN, p);
    }
}

比诺,

我不认为你必须选择其中一个而不是另一个。

将依赖类或接口移动到类构造函数或setter的行为遵循DI模式。传递给构造函数或集合的对象可以用Factory实现。

什么时候使用?使用开发人员擅长的模式。他们觉得什么最舒服,什么最容易理解。

您可以在这个链接中查看两种(和其他)方法在实际示例中的比较。

基本上,当需求发生变化时,如果您使用工厂而不是DI,您最终会修改更多的代码。

这对于手动DI也是有效的(例如,当没有外部框架为你的对象提供依赖关系,但你在每个构造函数中传递它们时)。