php - 什么时候依赖注入(inject)容器会变得太大,我该怎么办?

标签 php oop dependency-injection

我们都知道为什么依赖注入(inject)很棒 因为它使代码更少耦合,更易于测试,并且更易于阅读!然后有些人决定使用 依赖注入(inject)容器 喜欢 pimple为 PHP 提供协助 Dependency Inversion原理在SOLID .

因此,当使用 pimple 创建 DiC 时,将其传递给 Controller ​​,并在闭包中创建所有新对象,而闭包实际上仅在开发人员调用 $container['object'] 时才实例化。 , 这很棒!

但是当您拥有 时会发生什么?您的应用程序中非常大的一组类 ?说 1000+,你想要这些在容器中可用吗?

在开发方面,将所有这些都放在一个文件中将是一场噩梦。将它们分开的最佳方法是什么,或者替代建议更可取?

在分离方面,怎么样:

  • 创建容器
  • 包括几个文件,根据应用程序将类分组在一起
  • 增量添加到容器中,直到文件末尾包含

  • 另一方面,我知道 Symfony2 uses XML/YAML对于 DiC 配置,但实际上当应用程序包含如此多的类时,这并没有过多讨论事物的体系结构方面。

    当开发人员拥有如此庞大的代码库时,他们可以做什么?

    最佳答案

    假设您的所有类都将通过 DI 容器调用。

    先来个小对比案例:
    如果您去商店购买一条裤子,那么您有时会使用 DI。例如,您不必告诉您需要什么尺寸,帮助您的人拥有专业知识即可找到。你要说你想要什么样的裤子,店里的人会根据你的意愿给你一些裤子(或者让你知道那是不可能的)。一个不是 DI 的例子是所有这些裤子来自哪里的问题的答案。对于进入商店的顾客来说,这个问题的答案完全无关紧要。永远不会成为进入商店的理由,那里需要一条某种类型的裤子。
    你可以问某种类型的未指定问题,你会得到确切的答案。这就是DI的核心。如何完成与您无关,也与您无关。但你不能问任何事情。例如,你不能在布料店买到面包。问题必须与特定的 DI 主题(界面)相关。

    Pimple 是一个关联数组。它不是 DI - 容器。据你所知,DI-容器会返回一个接口(interface),DI-容器知道加载哪个实现。让我举个例子来告诉你 Pimple 不是 DI - 容器的地方。
    你在店里,你选了一条裤子,你想买。现在你要付钱了。如何?那又是DI。对您来说没问题,您有多种可用的交易方法,您可以选择一种。系统将如何回答对您来说并不有趣:您什么也不说,只需拿起钱包并开始付款。

    在 Pimple 中,您必须选择用于付款的对象。客户将不得不说“我需要支付对象”。在真正的 DI - 容器中,您是否只需要以合法的方式(接口(interface)行为)交出钱,并且基于输入数据,DI - 容器将知道选择哪种实现(现金、信用卡、万事达卡)。你不必担心。如果您仍然需要担心,为什么称其为依赖项 注塑 ? Pimple 是最好的服务定位器,但要使用 DI,您必须使用接口(interface)。否则没有什么可隐藏的,没有依赖注入(inject)。 :-)

    所以,不要将 Pimple 用于 DI。它不是 DI - 容器。如果您打算使用 Pimple(并且它可以很好地组织您的类(class)),那么不要将其称为 DI。它是最好的服务定位器,但它没有使用接口(interface)隐藏实现。因此它不能是 DI。

    尝试组织您的代码库。不同类的功能是什么?哪些类(class)需要 DI?我建议您只将 DI 用于执行功能需求的类。当您回到商店的情况时:商店人员直接与客户沟通的所有功能。不是为了实现如何走到后端试图找到另一条裤子。不是关于如何打开或关闭商店的过程。但是对于如何欢迎客户并询问某人想要什么类型的裤子,是的。
    在您的应用程序中:是否有直接与应用程序访问者交互的接口(interface)/类,您能否创建某种类型的契约(Contract)来描述交互?那就是那个 DI - 容器的设计。
    我不会到处使用 DI。 DI 带来了性能损失和维护问题。您使用的 DI 越多,您将拥有的层数越多,您就越不知道在哪里发生了什么。最好在最有利的地方使用 DI,也就是实现最有可能改变的地方,但调用者不知道接口(interface)已经改变,调用者也不会对这种改变感兴趣。如果您以此为指导,那么您能否区分哪些类通过 DI 容器隐藏,哪些类不隐藏。

    关于php - 什么时候依赖注入(inject)容器会变得太大,我该怎么办?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16461846/

    相关文章:

    java - 在 Java 中初始化子类参数的首选方法?

    symfony - 调用由包动态创建的服务的方法

    php - 是否可以在 $_GET | 中设置/插入新变量$_POST | $_ session |来自 TWIG 的 $_COOKIE?

    c++ - 使用抽象工厂的问题

    php - Magento 2 如何通过 url_key 获取类别

    PHP OOP - getter setter 是否用于防止更改属性值?

    C++:将对象的创建与使用分开(用于测试目的)

    android - Dagger @ContributesAndroidInjector ComponentProcessor 无法处理这个接口(interface)

    PHP,函数中的数据库连接。是否必须单独连接?

    php - 如何将多个变量从 ajax 传递到 php?