关于将DI / IoC容器集成到现有应用程序中的建议


10

我现在面临着将控制反转(IoC)容器集成到现有应用程序中的问题,并且我正在寻找一些建议,以最容易实现的最终目标是减少耦合,从而提高可测试性。尽管我通常不会将大多数类归类为上帝对象,但每个类都有太多的职责,并且由于静态,单例和缺乏接口而隐藏了依赖性。

这里有一些背景需要解决的挑战:

  • 很少使用依赖注入
  • 静态方法比比皆是-无论是工厂方法还是辅助方法
  • 单身人士相当普遍
  • 接口在使用时不太细
  • 对象经常通过基类引入不需要的依赖

我们的意图是,下次我们需要在特定区域中进行更改时,我们将尝试弄清实际上存在的但隐藏在诸如单例和静态变量之类的全局变量之后的依赖项。

我想这会使IoC容器在引入依赖项注入之后成为第二位,但是我希望可以遵循或考虑到一系列实践和建议,以帮助我们打破这些依赖关系。


3
我必须问现在这样做的原因...是什么促使这一变化?可维护性?可扩展性会因为它成倍增长?开发人员很无聊吗?
亚伦·麦克弗

1
我刚加入公司,正在尝试介绍一些“最佳做法”。我的主要目标是提高可测试性并减少耦合。我们可以轻松地将DI / IoC用于新代码,并且不打算立即更改所有现有代码,但是我想提出有关如何在下一次制作时更好地更改现有代码的建议。在那方面的变化。到目前为止,我在网上找到的唯一东西是:code.google.com/p/autofac/wiki/ExistingApplications
Kaleb Pederson

3
除非有大量的自动化单元/集成测试;除非为了最佳实践而存在问题,否则请修改现有的基础结构。即使您的单元/集成测试套件很可靠,我仍然会犹豫。
亚伦·麦克弗

1
@Aaron我希望听起来不是为了最佳实践而这样做。我们之所以进行更改,是因为使用现有的代码既困难又缓慢,并且在我们从事特定领域工作时会零碎地进行。很高兴,我们确实提供了一组合理的集成测试和一些单元测试来支持进行更改。
Kaleb Pederson

Answers:


8

为了实现这样的目标,您必须分步进行,其中的每一项都不是琐碎的事,但可以实现。在开始之前,您必须了解您不能急于完成此过程。

  1. 定义应用程序的主要子系统,并interface为每个子系统定义一个。该接口应定义系统其他部分用来与之对话的方法。注意:您可能需要采取多次以上的步骤。
  2. 提供该接口的包装实现,委派给现有代码。该练习的目的是避免大量重写,而是重构代码以使用新接口,即减少系统中的耦合。
  3. 设置IoC容器,以使用您创建的接口和实现来构建系统。在此阶段,您需要注意实例化IoC容器,以便它可以启动应用程序。即,如果您在servlet环境中,请确保可以在servlet init()方法中获取/创建容器。
  4. 在每个子系统中再次执行相同的操作,这一次在重构时,您会将存根实现转换为真实的东西,而真实的东西又使用接口与其组件进行通信。
  5. 根据需要重复操作,直到组件大小与功能之间达到平衡为止。

完成后,您应该在系统中仅有的静态方法才是真正的函数,例如查看Collections类或Math类。任何静态方法都不应尝试直接访问其他组件。

这将需要很多时间,因此要进行计划。确保在执行重构时,您的设计方法变得越来越牢固。一开始它会很痛苦。您正在反复迭代地更改应用程序的设计。


好建议。进行此类更改时,我也请其他人在此提出建议:code.google.com/p/autofac/wiki/ExistingApplications
Kaleb Pederson

7

选择有效地使用旧版代码并遵循他的建议。从构建涵盖代码的孤岛开始,逐步向结构更完善的应用程序发展。试图进行全面变革是灾难的根源。


喜欢那本书!
Martijn Verburg

很好的推荐。尽管几年前我读了一半,但我想我现在可以从中受益匪浅了。
Kaleb Pederson

这很有趣,选择的答案基本上是本书的总结;)当然,羽毛的细节要多得多。
迈克尔·布朗

5

引入IoC的主要原因是模块解耦。尤其是Java的问题是new操作员提供的非凡的强绑定,再加上这意味着调用代码确切知道它将使用哪个模块。

引入工厂是为了将这些知识转移到中心位置,但最后您仍然可以使用new/ singleton 来硬连接模块以保持硬绑定,或者您可以读取配置文件并使用reflecting / Class.forName来进行重构。 。

如果您没有将目标模块化,那么IoC不会给您任何东西。

引入单元测试很可能会改变这一点,因为您将需要模拟未测试的模块,并且使用相同的代码来处理此模块以及实际生产模块的最简单方法是使用IoC框架注入适当的模块。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.