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

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

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

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


当前回答

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

其他回答

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

使用依赖注入框架,开发人员不需要手动准备和设置类实例的依赖项,这一切都是事先准备好的。

对于工厂,开发人员必须手工完成,并使用这些依赖对象创建类实例。

区别主要在于这一行中调用工厂并获取构造的对象,以及编写工厂方法来创建和设置所有内容(尽管可以认为,在依赖注入框架中,通过连接和配置对象关系,这也必须在一定程度上完成)。

如果是工厂,你就得打电话给任何需要这种东西的工厂。 使用依赖注入框架,你可以在类实例创建时依赖对象的存在。

我的观点是,工厂方法更静态,因为它的实现相当固定,而依赖注入框架更动态,因为类实例的实际组合更容易改变(例如。为了测试目的)在运行时。

理论

这里有两点需要考虑:

谁创建对象:

[Factory]:你必须写如何创建对象。您有独立的Factory类,其中包含创建逻辑。 [依赖注入]:在实际情况下,这是由外部框架完成的(例如在Java中是spring/ejb/guice)。注入“神奇地”发生,无需显式地创建新对象。

它管理的对象类型:

[Factory]:通常负责有状态对象的创建 [依赖注入]:更可能创建无状态对象


关于如何在一个项目中同时使用工厂注入和依赖注入的实例

我们想要建造什么

用于创建包含多个名为orderline的条目的订单的应用程序模块。

体系结构

让我们假设我们想要创建以下分层架构:

域对象可以是存储在数据库中的对象。 存储库(DAO)帮助从数据库检索对象。 服务为其他模块提供API。允许对订单模块进行操作。

域层和工厂的使用

数据库中的实体是Order和OrderLine。Order可以有多个orderline。

现在是重要的设计部分。这个模块之外的模块是否应该自己创建和管理orderline ?不。只有当订单与之关联时,订单行才应该存在。最好能将内部实现隐藏到外部类。

但是如何在不了解OrderLines的情况下创建Order呢?

工厂

想要创建新订单的人使用了OrderFactory(它将隐藏关于我们如何创建订单的细节)。

这就是它在IDE中的样子。域包外部的类将使用OrderFactory而不是Order内部的构造函数。

依赖注入 依赖注入更常用于无状态层,如存储库和服务。

OrderRepository和OrderService由依赖注入框架管理。 存储库负责管理数据库上的CRUD操作。Service注入存储库并使用它来保存/查找正确的域类。

注入框架是工厂模式的实现。

这完全取决于你的要求。如果您需要在应用程序中实现工厂模式,那么您的需求极有可能由众多注入框架实现中的一个来满足。

只有在任何第三方框架都不能满足您的需求时,您才应该推出自己的解决方案。编写的代码越多,需要维护的代码就越多。代码是一种负债而不是资产。

关于应该使用哪个实现的争论没有理解应用程序的体系结构需求那么重要。

简单来说,依赖注入和工厂方法分别意味着推和拉机制。

拉机制:类间接依赖于工厂方法,工厂方法又依赖于具体类。

推送机制:根组件可以在一个位置配置所有依赖组件,从而促进高维护和松耦合。

使用Factory方法时,创建新对象的责任仍然由类承担(尽管是间接的),而使用依赖注入时,责任是外包的(尽管是以泄露抽象为代价)。