使用IOC容器会降低应用程序的速度,因为大多数容器都使用反射器。它们还会使您的代码更难理解(?)。光明的一面;它们可以帮助您创建更松散耦合的应用程序,并使单元测试更容易。使用/不使用IOC容器还有其他优缺点吗?
答案 0 :(得分:19)
如果您以简单的方式使用IOC容器,则仅在启动时使用反射 - 应用程序连接起来,然后在没有容器干预的情况下正常运行。当然,如果您在开始运行后使用IOC来解决依赖关系,那可能会略有不同 - 尽管我仍然期望它可以懒惰地解析并缓存,除非您已将其配置为每个都创建新实例时间。
至于让代码更难理解 - 恰恰相反!通过明确声明依赖关系,可以更容易地理解每个组件,并且配置文件清楚地表明整个应用程序是如何挂起的。
答案 1 :(得分:7)
嗯,我认为我遇到的一个问题是,一些开发人员似乎无法掌握IoC。我们有几个人除了他们不理解他们之外没有任何理由反对它。 (并不是说这是反对某事的一个坏理由,完全没有。)
它确实增加了一些似乎总是让某人或其他人感到困惑的抽象,但我认为在大多数情况下,优点远远超过缺点。
答案 2 :(得分:7)
我认为,如果您对如何使用IOC有专业的了解并且倾向于编写优秀的代码,那么可以说是公平的,那么IOC将使您的代码更易于理解除最小的系统之外的所有代码。
但是,如果你在大多数类/方法非常庞大并且重构概念尚未成熟的地方工作,那么尝试使用IOC可能只是为了让软件更难理解。国际奥委会也必须由项目所有人参与,因此可能需要考虑。
我认为国际奥委会是锦上添花;我喜欢结冰,但只喜欢美味的蛋糕。如果蛋糕开始不好吃,请先将蛋糕整理出来。
至于使用IOC的性能开销,在大多数情况下我不认为这是一个问题。开销不需要很大,并且考虑到当今CPU的速度,大多数运行时间可能仍然是数据访问。如果一个IOC被证明对于给定的代码有点慢,我会考虑添加一些返回对象的缓存,或从该位代码中删除IOC 。
答案 3 :(得分:3)
到目前为止,我同意所有答案。
我想补充的是,它会产生一些开销,因此它不适合小型应用程序。
使用IoC,中型和大型应用程序受益最多。
您还可以查看此问题,了解有关优缺点的更多信息:Castle Windsor Are There Any Downsides?
答案 4 :(得分:3)
我认为关于降低执行速度的假设与“C比C#/ Java更快”的论证大致相同。虽然这个陈述可能对于特定操作和/或结构上简单的任务都是如此,但是当时复杂度上升并非如此。
当代码大小增加时,DI框架让您专注于对象创建和依赖关系的方式可以创建更高效的系统。对于大型应用程序,我几乎可以肯定基于DI框架的代码将胜过任何替代解决方案。运行时中的冗余很少,因此很难提高效率!大多数额外开销也只是在第一次加载时。
高级DI容器还可让您在没有容器的情况下进行“范围”魔术。使用范围代理,spring可以执行以下操作:
A Singleton
|
B Singleton
|
C Prototype (per-invocation)
|
D Singleton
|
E Session scope (web app)
|
F Singleton
实际上,您可以拥有十层单例对象,并突然显示会话作用域。
像安全一样的东西可以以完全不同的方式注入。通常存在一个经典的悖论:GUI层通常需要具有安全权限的复杂知识。服务层通常也需要这个,但通常在不同的细节层次(通常不如gui详细)。经典的方法是将其作为参数发送,将其放在线程本地或询问服务。有了弹簧,你可以直接将它注入你需要的地方而不需要其他人知道。
这实际上改变了应用程序开发的整体。我真的很难适应这一点,但在这种痛苦之后,我发现它确实与事物应该如何接近(而不是我们如何学会这样做)。
所以我认为DI框架有可能改变你制作节目的方式,而不仅仅是DI。这不仅仅是一种称赞新的美化方式。
答案 5 :(得分:2)
在大多数情况下,您甚至不会注意到性能损失,因为对于“单例”对象,所有初始化仅执行一次。我还认为IoC使得理解代码变得与众不同:相反,IoC风格的开发迫使你创建小的连贯类,这反过来更容易理解。
答案 6 :(得分:1)
如果您正在编写业务应用程序,使用控制反转和依赖注入容器(与其他敏捷实践和工具结合使用)将帮助您提高生产力和可靠性。
此外,您的应用程序可能会花费大部分CPU时间等待资源或等待人工交互并且无用。你的应用程序应该有足够的马力来备用几微秒的反射。