引用的大多数使用依赖注入的例子,我们也可以使用工厂模式来解决。看起来当涉及到使用/设计时,依赖注入和工厂之间的区别是模糊或稀薄的。
曾经有人告诉我,你如何使用它才会有所不同!
我曾经使用StructureMap一个DI容器来解决一个问题,后来我重新设计了它来使用一个简单的工厂,并删除了对StructureMap的引用。
谁能告诉我它们之间的区别在哪里使用什么,这里的最佳实践是什么?
引用的大多数使用依赖注入的例子,我们也可以使用工厂模式来解决。看起来当涉及到使用/设计时,依赖注入和工厂之间的区别是模糊或稀薄的。
曾经有人告诉我,你如何使用它才会有所不同!
我曾经使用StructureMap一个DI容器来解决一个问题,后来我重新设计了它来使用一个简单的工厂,并删除了对StructureMap的引用。
谁能告诉我它们之间的区别在哪里使用什么,这里的最佳实践是什么?
当前回答
有些问题用依赖注入很容易解决,而用一套工厂就不那么容易解决了。
一方面,控制反转和依赖注入(IOC/DI)与另一方面,服务定位器或工厂套件(factory)之间的一些区别是:
IOC/DI is a complete ecosystem of domain objects and services in and of itself. It sets everything up for you in the way you specify. Your domain objects and services are constructed by the container, and do not construct themselves: they therefore do not have any dependencies on the container or on any factories. IOC/DI permits an extremely high degree of configurability, with all the configuration in a single place (construction of the container) at the topmost layer of your application (the GUI, the Web front-end).
工厂抽象了域对象和服务的一些构造。但是领域对象和服务仍然负责弄清楚如何构造自己,以及如何获得它们所依赖的所有东西。所有这些“活动的”依赖项都会在应用程序的所有层中进行筛选。没有一个地方可以配置所有的东西。
其他回答
当您确切地知道此时需要什么类型的对象时,就可以使用依赖项注入。而在工厂模式的情况下,你只是把创建对象的过程委托给工厂,因为你不清楚你需要什么类型的对象。
注入框架是工厂模式的实现。
这完全取决于你的要求。如果您需要在应用程序中实现工厂模式,那么您的需求极有可能由众多注入框架实现中的一个来满足。
只有在任何第三方框架都不能满足您的需求时,您才应该推出自己的解决方案。编写的代码越多,需要维护的代码就越多。代码是一种负债而不是资产。
关于应该使用哪个实现的争论没有理解应用程序的体系结构需求那么重要。
我知道这个问题很老了,但我想补充一下我的观点,
我认为依赖注入(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!!
不管怎样,评论区是开放的,你可以杀了我。
我使用这两种方法来创建反转控制策略,为在我之后需要维护它的开发人员提供了更强的可读性。
我使用工厂来创建不同的层对象(业务,数据访问)。
ICarBusiness carBusiness = BusinessFactory.CreateCarBusiness();
另一个开发人员会看到这一点,当创建业务层对象时,他会在BusinessFactory中查看,智能感知会为开发人员提供所有可能创建的业务层。不需要玩游戏,找到我想要创建的界面。
这个结构已经是控制反转了。我不再负责创建特定的对象。但是您仍然需要确保依赖注入能够轻松地更改内容。 创建自己的自定义依赖注入是荒谬的,所以我使用Unity。在CreateCarBusiness()中,我要求Unity解决哪个类属于这个和它的生命周期。
所以我的代码工厂依赖注入结构是:
public static class BusinessFactory
{
public static ICarBusiness CreateCarBusiness()
{
return Container.Resolve<ICarBusiness>();
}
}
现在我两者兼得。我的代码对于其他开发人员来说也更易于阅读,因为我使用的对象的范围,而不是构造函数依赖注入,它只是说在创建类时每个对象都是可用的。
当我创建单元测试时,我使用它将我的数据库数据访问更改为自定义编码的数据访问层。我不希望我的单元测试与数据库、网络服务器、电子邮件服务器等通信。他们需要测试我的业务层,因为这是智能所在。
[Factory] ->有一个基于请求参数创建类的类。毕竟,“工厂”在现实世界中也为你制造“物品”。你可以让你的汽车供应商工厂生产(免费:)特斯拉。1给你。
[DI] ->一个(服务)容器,用于存储接口(压缩类)。你不关心创建对象。你只需要让某个人/某个地方实现它,细节和其他东西对你、调用者或消费者都不重要。
DI是SOLID原则中“D”的基础。