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

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

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

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


当前回答

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

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

检查这个链接:依赖注入

其他回答

[Factory] ->有一个基于请求参数创建类的类。毕竟,“工厂”在现实世界中也为你制造“物品”。你可以让你的汽车供应商工厂生产(免费:)特斯拉。1给你。

[DI] ->一个(服务)容器,用于存储接口(压缩类)。你不关心创建对象。你只需要让某个人/某个地方实现它,细节和其他东西对你、调用者或消费者都不重要。

DI是SOLID原则中“D”的基础。

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

如果传递的参数可以在工厂中分组,那么它也是构造函数过度注入的一个很好的解决方案,看看下面的代码*):

public AddressModelFactory(IAddressAttributeService addressAttributeService,
        IAddressAttributeParser addressAttributeParser,
        ILocalizationService localizationService,
        IStateProvinceService stateProvinceService,
        IAddressAttributeFormatter addressAttributeFormatter)
    {
        this._addressAttributeService = addressAttributeService;
        this._addressAttributeParser = addressAttributeParser;
        this._localizationService = localizationService;
        this._stateProvinceService = stateProvinceService;
        this._addressAttributeFormatter = addressAttributeFormatter;
    }

看看构造函数,你只需要在那里传递IAddressModelFactory,所以参数更少*):

 public CustomerController(IAddressModelFactory addressModelFactory,
        ICustomerModelFactory customerModelFactory,
        IAuthenticationService authenticationService,
        DateTimeSettings dateTimeSettings,
        TaxSettings taxSettings,
        ILocalizationService localizationService,
        IWorkContext workContext,
        IStoreContext storeContext,
        ICustomerService customerService,
        ICustomerAttributeParser customerAttributeParser,
        ICustomerAttributeService customerAttributeService,
        IGenericAttributeService genericAttributeService,
        ICustomerRegistrationService customerRegistrationService,
        ITaxService taxService,
        CustomerSettings customerSettings,
        AddressSettings addressSettings,...

你可以看到在CustomerController中传递了很多参数,是的,你可以看到这是构造函数的过度注入,但这就是DI的工作方式。CustomerController没有任何问题。

*)代码来自nopCommerce。

工厂设计模式

工厂设计模式的特点是

一个接口 实现类 一个工厂

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

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

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

依赖注入

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

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

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

例子:

public class MyClass{

  MyInterface find= null;

  //Constructor- During the object instantiation

  public MyClass(MyInterface myInterface ) {

       find = myInterface ;
  }

  public void myMethod(){

       find.doSomething();

  }
}

Life cycle management is one of the responsibilities dependency containers assume in addition to instantiation and injection. The fact that the container sometimes keep a reference to the components after instantiation is the reason it is called a "container", and not a factory. Dependency injection containers usually only keep a reference to objects it needs to manage life cycles for, or that are reused for future injections, like singletons or flyweights. When configured to create new instances of some components for each call to the container, the container usually just forgets about the created object.

来自:http://tutorials.jenkov.com/dependency-injection/dependency-injection-containers.html