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

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

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

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


当前回答

依赖注入的一个缺点是它不能用逻辑初始化对象。例如,当我需要创建一个随机名称和年龄的字符时,DI不是工厂模式的选择。使用工厂,我们可以很容易地从对象创建中封装随机算法,它支持一种称为“封装变化”的设计模式。

其他回答

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.

工厂设计模式

工厂设计模式的特点是

一个接口 实现类 一个工厂

当你这样问自己时,你可以观察到一些事情

工厂什么时候为实现类创建对象——运行时还是编译时? 如果您想在运行时切换实现,该怎么办?-不可能

这些是由依赖注入处理的。

依赖注入

您可以使用不同的方式注入依赖项。为了简单起见,让我们使用接口注入

在DI中,容器创建所需的实例,并将它们“注入”到对象中。

这样就消除了静态实例化。

例子:

public class MyClass{

  MyInterface find= null;

  //Constructor- During the object instantiation

  public MyClass(MyInterface myInterface ) {

       find = myInterface ;
  }

  public void myMethod(){

       find.doSomething();

  }
}

我知道这个问题很老了,但我想补充一下我的观点,

我认为依赖注入(DI)在很多方面类似于可配置的工厂模式(FP),从这个意义上说,你可以用DI做任何事情,你也可以用这样的工厂来做。

实际上,如果你使用spring为例,你可以选择自动装配资源(DI)或做这样的事情:

MyBean mb = ctx.getBean("myBean");

然后使用'mb'实例来做任何事情。这不是一个对工厂的调用,它将返回一个实例吗??

我注意到的大多数FP示例之间唯一真正的区别是,您可以在xml或其他类中配置“myBean”是什么,框架将作为工厂工作,但除此之外是一样的事情,您当然可以有一个工厂来读取配置文件或根据需要获得实现。

如果你问我的意见(我知道你没有),我相信DI做了同样的事情,但只是增加了开发的复杂性,为什么?

嗯,首先,为了让您知道用于DI自动装配的任何bean的实现是什么,您必须进入配置本身。

但是…您不必知道正在使用的对象的实现,这种承诺又如何呢?啐!严重吗?当你使用这样的方法时……你不就是写实现的那个人吗??即使你没有,你不是几乎所有的时间都在看如何实现它应该做什么??

最后一点,不管DI框架向你承诺了多少,你将构建与它解耦的东西,不依赖于它们的类,如果你正在使用一个框架,你将围绕它构建一切,如果你不得不改变方法或框架,这将不是一个简单的任务……!…但是,由于您围绕特定的框架构建所有内容,而不是担心什么是最适合您的业务的解决方案,那么在这样做时,您将面临一个更大的问题。

事实上,我所能看到的FP或DI方法的唯一真正的业务应用是,如果你需要在运行时改变正在使用的实现,但至少我所知道的框架不允许你这样做,你必须在开发时让所有的配置都完美无缺,如果你需要使用另一种方法。

因此,如果我有一个类,它在同一个应用程序的两个作用域中执行不同的操作(比如说,同一个公司的两个控股公司),我必须配置框架来创建两个不同的bean,并调整我的代码以使用每个bean。这是不是和我只是写这样的东西是一样的

MyBean mb = MyBeanForEntreprise1(); //In the classes of the first enterprise
MyBean mb = MyBeanForEntreprise2(); //In the classes of the second enterprise

和这个一样:

@Autowired MyBean mbForEnterprise1; //In the classes of the first enterprise
@Autowired MyBean mbForEnterprise2; //In the classes of the second enterprise

这:

MyBean mb = (MyBean)MyFactory.get("myBeanForEntreprise1"); //In the classes of the first enterprise
MyBean mb = (MyBean)MyFactory.get("myBeanForEntreprise2"); //In the classes of the second enterprise

在任何情况下,您都必须更改应用程序中的某些内容,无论是类还是配置文件,但您必须重新部署它。

这样做不是很好吗?

MyBean mb = (MyBean)MyFactory.get("mb"); 

通过这种方式,您可以设置工厂的代码以在运行时获得正确的实现,这取决于登录的用户企业??这很有帮助。您只需添加一个带有新类的新jar,并在运行时设置规则(或者如果您保留此选项,则添加一个新的配置文件),无需更改现有类。这将是一个动态工厂!

这不是比为每个企业编写两个配置,甚至为每个企业编写两个不同的应用程序更有帮助吗?

You can tell me, I don't need to do the switch at runtime ever, so I configure the app, and if I inherit the class or use another implementation I just change the config and redeploy. Ok, that can also be done with a factory. And be honest, how many times do you do this? maybe only when you have an app that's going to be used somewhere else in your company, and you are going to pass the code to another team, and they will do things like this. But hey, that can also be done with the factory, and would be even better with a dynamic factory!!

不管怎样,评论区是开放的,你可以杀了我。

我建议保持概念的简单明了。依赖注入更像是一种松散耦合软件组件的体系结构模式。工厂模式只是将创建其他类的对象的职责分离给另一个实体的一种方法。工厂模式可以被称为实现依赖注入的工具。依赖注入可以通过多种方式实现,比如使用构造函数进行依赖注入,使用映射xml文件等。

依赖注入(DI)和工厂模式相似的原因是它们是控制反转(IoC)的两种实现,IoC是一种软件架构。简单地说,它们是同一问题的两种解决方案。

因此,为了回答这个问题,工厂模式和依赖注入模式之间的主要区别在于如何获得对象引用。依赖项注入顾名思义就是将引用注入或提供给您的代码。使用工厂模式,您的代码必须请求引用,以便您的代码获取对象。这两种实现都删除或解耦了代码与所使用的对象引用的底层类或类型之间的链接。

值得注意的是,工厂模式(或者实际上是抽象工厂模式,即返回返回对象引用的新工厂的工厂)可以被编写为在运行时动态地选择或链接到被请求的对象类型或类。这使得它们与服务定位器模式非常相似(甚至比DI更相似),后者是IoC的另一个实现。

工厂设计模式相当古老(就软件而言),并且已经存在了一段时间。由于IoC体系结构模式最近的流行,它正在复苏。

我想当涉及到IoC设计模式时:注入器被注入,定位器被定位,工厂被重构。