【问题标题】:Abstract factory pattern on top of IoC?IoC 之上的抽象工厂模式?
【发布时间】:2010-12-31 21:25:33
【问题描述】:

我决定在一个更大的项目中使用 IoC 原则。但是,我想弄清楚困扰我很久的事情。我得出的结论是 IoC 容器是一种架构模式,而不是设计模式。换句话说,任何类都不应该知道它的存在,容器本身应该在应用层使用来拼接所有组件。从本质上讲,它成为了一种选择,在精心设计的面向对象模型之上。 话虽如此,如何在不将 IoC 容器撒在各处(无论它们是否被抽象)的情况下访问已解析的类型?我在这里看到的唯一选择是利用抽象工厂,它使用 IoC 容器来解析具体类型。这应该很容易换成一组标准工厂。这是一个好方法吗?这里有没有人用过它,它对你的效果如何?还有其他的吗?

谢谢!

【问题讨论】:

    标签: inversion-of-control factory containers


    【解决方案1】:

    在您的应用程序的最顶部,您将需要一个加载 IOC 上下文的 Bootstrap 类。然后,此上下文将提供实际实例化的对象,因此充当工厂。

    但这应该只发生在极少数对象上,并且您的 Bootstrap/Factory 类的用户应该尽可能少地了解底层架构。例如,如果您完全通过 IOC 配置了一个 HTTP 服务器对象并且您想要启动它,您的 Bootstrap 类只需要提供一个 getHttpServer() 方法。那么你的程序主方法只需要调用 Bootstrap.getHttpServer().start() 就可以运行了。

    其他对象的连接已经由应用程序上下文完成,例如您通过作为对象 B 一部分的 IOC 配置对象 A,因此您可以使用对象 A 的引用来配置对象 B。它们通常不需要了解容器或工厂。

    【讨论】:

      【解决方案2】:

      正如您已经了解的那样,依赖注入 (DI) 本身只是模式和技术的集合。

      在应用程序的根部,我们连接了所有必要的对象图。这个地方叫做Composition Root,我们可以使用DI Container来为我们做这个接线,也可以手动(Pure DI)。

      关键在于,您的应用程序中只有一个地方强烈引用了特定技术(您的 DI 容器)。应用程序的其余部分完全不知道对象图是如何连接起来的 - 重要的是所有必需的依赖项都已正确注入(您可以将 Constructor InjectionNull Guards 保证确实如此)。

      Abstract Factory 模式对于 DI 来说是一个非常有用的模式。本质上,在以下情况下使用抽象工厂:

      • 您需要提供一个或多个仅在运行时才知道的参数,然后才能解决依赖关系。
      • 从概念上讲,依赖项的生命周期比使用者的生命周期短。

      此处提供示例和更多信息:

      【讨论】:

      • 我想我快到了。留在我这里 :) 假设我有 IFruit 接口,它是由 Apple 类实现的。注册此具体类型后,我想在 Windows 窗体中的按钮单击事件中使用它。如果不从按钮事件显式访问 IoC 容器,我将如何进入 Apple 课程?
      • 这取决于:您的应用程序中有很多 IFruit 实例,还是只有一个?如果只有一个,它应该已经使用按钮单击处理程序注入到类中。如果有很多,您很可能需要一个可以从其他运行时值创建 IFruit 实例的 IFruitFactory。在后一种情况下, IFruitFactory 将是注入的依赖项。
      • 考虑到只有一个 IFruit 实例存在,我看到它通过按钮单击事件注入 Form 类的唯一方法是,如果我更改表单构造函数以包含 IFruit 接口,然后注册表单本身使用 IoC 容器执行构造函数注入。这听起来正确吗?感谢您的帮助!
      • 完美!我想我现在很幸福。感谢您的帮助!
      • IoC 容器(如 CDI、Spring、Guice 等)如果你仔细观察你会发现 IoC 看起来就像抽象工厂。调用 container.getBeanForType(BeanType.class) 我们正在执行创建过程,而不知道如何在给定平台上创建具体对象。上述平台由一组所有可注入 bean(条件 bean、配置文件、在执行更复杂条件的代码中动态创建的 bean 等)定义。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-06
      • 1970-01-01
      • 1970-01-01
      • 2023-03-30
      相关资源
      最近更新 更多