引用的大多数使用依赖注入的例子,我们也可以使用工厂模式来解决。看起来当涉及到使用/设计时,依赖注入和工厂之间的区别是模糊或稀薄的。
曾经有人告诉我,你如何使用它才会有所不同!
我曾经使用StructureMap一个DI容器来解决一个问题,后来我重新设计了它来使用一个简单的工厂,并删除了对StructureMap的引用。
谁能告诉我它们之间的区别在哪里使用什么,这里的最佳实践是什么?
引用的大多数使用依赖注入的例子,我们也可以使用工厂模式来解决。看起来当涉及到使用/设计时,依赖注入和工厂之间的区别是模糊或稀薄的。
曾经有人告诉我,你如何使用它才会有所不同!
我曾经使用StructureMap一个DI容器来解决一个问题,后来我重新设计了它来使用一个简单的工厂,并删除了对StructureMap的引用。
谁能告诉我它们之间的区别在哪里使用什么,这里的最佳实践是什么?
当前回答
简单来说,依赖注入和工厂方法分别意味着推和拉机制。
拉机制:类间接依赖于工厂方法,工厂方法又依赖于具体类。
推送机制:根组件可以在一个位置配置所有依赖组件,从而促进高维护和松耦合。
使用Factory方法时,创建新对象的责任仍然由类承担(尽管是间接的),而使用依赖注入时,责任是外包的(尽管是以泄露抽象为代价)。
其他回答
[Factory] ->有一个基于请求参数创建类的类。毕竟,“工厂”在现实世界中也为你制造“物品”。你可以让你的汽车供应商工厂生产(免费:)特斯拉。1给你。
[DI] ->一个(服务)容器,用于存储接口(压缩类)。你不关心创建对象。你只需要让某个人/某个地方实现它,细节和其他东西对你、调用者或消费者都不重要。
DI是SOLID原则中“D”的基础。
我相信DI是一种配置或即时化bean的方法。DI可以通过很多方式来实现,比如构造函数,setter-getter等等。
工厂模式只是实例化bean的另一种方式。此模式将主要用于必须使用工厂设计模式创建对象时,因为在使用此模式时,您不配置bean的属性,只实例化对象。
检查这个链接:依赖注入
当我读到关于DI的文章时,我也有同样的问题。 最后,这就是我所理解的,但如果我错了,请纠正我。
“很久以前,有一些小国,它们有自己的管理机构,根据自己的成文规则进行控制和决策。后来形成了一个大政府,消除了所有这些小的管理机构,这些机构只有一套规则(宪法),并通过法院执行。”
小王国的管理机构是“工厂”
大政府是“依赖注入器”。
工厂设计模式
工厂设计模式的特点是
一个接口 实现类 一个工厂
当你这样问自己时,你可以观察到一些事情
工厂什么时候为实现类创建对象——运行时还是编译时? 如果您想在运行时切换实现,该怎么办?-不可能
这些是由依赖注入处理的。
依赖注入
您可以使用不同的方式注入依赖项。为了简单起见,让我们使用接口注入
在DI中,容器创建所需的实例,并将它们“注入”到对象中。
这样就消除了静态实例化。
例子:
public class MyClass{
MyInterface find= null;
//Constructor- During the object instantiation
public MyClass(MyInterface myInterface ) {
find = myInterface ;
}
public void myMethod(){
find.doSomething();
}
}
从表面上看,他们是一样的
简单来说,工厂模式,创建模式帮助我们创建一个对象——“定义一个创建对象的接口”。如果我们有一个键值类型的对象池(例如Dictionary),将键传递给工厂(我指的是简单工厂模式),您可以解析类型。完成工作! 另一方面,依赖注入框架(如结构图、Ninject、Unity等)似乎也在做同样的事情。
但是…“不要白费力气”
从架构的角度来看,这是一个绑定层,“不要白费力气”。
对于企业级应用程序,依赖注入的概念更像是一个定义依赖关系的体系结构层。为了进一步简化,您可以将其视为一个单独的类库项目,它进行依赖解析。主应用程序依赖于这个项目,其中依赖项解析器引用其他具体实现和依赖项解析。
除了来自Factory的“GetType/Create”之外,我们通常还需要更多的特性(使用XML定义依赖关系、模拟和单元测试等)。既然您引用了结构图,那么请查看结构图特性列表。这显然不仅仅是解决简单的对象映射。别白费力气了!
如果你只有一把锤子,那么所有东西看起来都像钉子
根据您的需求和您构建的应用程序类型,您需要做出选择。如果它只有很少的项目(可能是一个或两个..)并且涉及很少的依赖项,您可以选择一个更简单的方法。这就像使用ADO . net数据访问而不是使用实体框架进行简单的1或2个数据库调用,在这种情况下引入EF是多余的。
但是对于一个更大的项目,或者如果你的项目变得更大,我强烈建议有一个带有框架的DI层,并留出空间来改变你使用的DI框架(在主应用程序中使用Facade (Web应用程序,Web Api, Desktop..等)。