【问题标题】:PHP MVC: Injecting utility/helper class instances into base classes as dependenciesPHP MVC:将实用程序/帮助程序类实例作为依赖项注入基类
【发布时间】:2017-06-03 22:33:16
【问题描述】:

在我的 HMVC 项目中,我实现了一个 Arrays 类。它的 STATIC 方法总体上用于处理多维数组上的各种操作。除了这个类,我也使用类似的类:FilesImagesPrinterMessagesClasses 等。但我不想再在我的项目中使用任何静态或单例了。

我将它们视为助手,最终类具有用于仅在项目组件上或与它们一起执行特定任务的方法(合并数组、调整图像大小、上传/打印文件等)。因此,我想...尽量减少它们在我的项目中的分布。

例如,我认为在每个子控制器中传递 Arrays 对象并不是最佳选择,因为在基本控制器类的构造函数中必须合并一些数组。

我想问一下:

  • 我实际上在基本控制器类中合并数组是错误的,还是真的会出现这种情况?
  • 如果没有错,那么我只能选择将实用程序类Arrays作为构造函数依赖传递,而static问题将通过这种方式优雅地解决。这是真的吗,还是有更好的选择?

我会很感激你的任何观点。

非常感谢!


附注:

这是Arrays类,如果你需要看一下:

<?php

namespace MYMVC\Utils;

/**
 * Arrays: utility class to handle operations on multidimensional arrays.
 */
class Arrays {

    /* ------------------------------------------------------------- */
    /* Keypath format: '{key0}/{key1}/{key2}/{key3}/{searched-key}'. */
    /* ------------------------------------------------------------- */

    /** Set the value in array at the specified keypath. [...] */

    public static function setArrayValue(&$array, $keypath, $value, $delimiter = '/') { ... }


    /** Get a tree structure from the specified keypath. [...] */

    public static function buildArrayTree($keypath, $value, $delimiter = '/') { ... }


    /** Check if the specified keypath exists in array. [...] */

    public static function arrayKeyExists(&$array, $keypath, $delimiter = '/') { ... }


    /** Get the array value from the specified keypath. [...] */

    public static function getArrayValue(&$array, $keypath, $delimiter = '/') { ... }


    /** Merge multiple multidimensional arrays. [...] */

    public static function mergeMultipleArrays(/* func_get_args */) { ... }


    /** Merge the top multidimensional array over the base multidimensional array. [...] */

    public static function mergeArrays($base, $top) { ... }

}

【问题讨论】:

  • 真的应该注射吗? - 为什么应该注射?您是否需要能够将Arrays 类型替换为另一个类? Arrays 是否需要其他依赖项?然后在你的课程中像Arrays::mergeMultipleArrays 一样使用它。没关系。
  • @Federkun 谢谢你的回答。你问的好。我编辑了我的问题,以某种方式揭示我想要实现的目标以及我如何看待它。这些类本身是最终类,甚至不要求任何依赖项。只是被动砖作为其方法的封装。
  • 由于您不需要通过注入一些依赖项来自定义助手的使用,您只需从您的类对助手进行一个简单的函数调用。您没有任何理由将您的 Arrays 对象替换为该类的另一个子类型。
  • @Federkun 我刚刚意识到,像Files 这样的实用程序类实际上可以具有一个或多个依赖项(文件名、路径、类型等)。而且因为我不想再使用 static 了,所以我必须将它作为依赖项传递给需要的地方。你能根据这些变化给我一个分析器吗?我会很感激的。谢谢你。 P.S:不幸的是,我没有具体的例子来说明清楚,因为我只使用了早期在静态系统上开发时的例子。然后我只是静态地打电话给助手,一切都解决了。我不想再这样了。

标签: php oop design-patterns model-view-controller mvvm


【解决方案1】:

Arrays::mergeArrays 之类的东西没有错。你不介意在你的课堂上打电话给in_arrayarray_merge,不是吗?如果您愿意,您可以将 Arrays 称为“实用程序”类,但我认为您不能为 Files 做同样的事情。

如果您当前的问题是“我不想将 xyz 对象传递给每个子控制器”,那么通常您会有以下想法:

  • 只需将 DIC 注入您的控制器即可。然后从中检索您的依赖项。这就是所谓的“服务定位器”,它被许多框架广泛使用。它的优点是您可以仅在需要时才需要依赖项。但它有一系列的缺点。没有它你的对象就不能存在,你的类也不能轻易地被嘲笑。这就是为什么它被认为是一种反模式。

  • 在控制器中显式注入您的依赖项(即:Files)。为什么要隐藏控制器依赖于Files 的事实?这里唯一的问题是,尤其是对于控制器,许多依赖项并不总是被所有类的方法使用。这更像是一个性能问题,您可以考虑通过多种方式解决它(例如: Action object)。

选择适合你的。

【讨论】:

  • 我不得不说,静态、单例和服务定位器对我来说是不行的。从来没有 :-) 但我真的很喜欢这种方式,你如何客观地将它们作为解决方案呈现给我(因为它们确实是一个),同时你向我展示了它们是一种反模式的事实。在这方面很好的答案。继续...
  • 续:我真正的问题不是我必须在基础控制器中注入实用程序/帮助程序实例(例如),而是我必须在基础中合并数组(例如)类的构造函数。那是我不确定:我不想仅仅因为我在构造函数中合并数组时做出错误的决定而注入一些东西。继续...
  • 续:请给我几分钟时间阅读“Action object”文档,我会回来的。
  • 你的答案绝对是正确的。不仅你给了我一个坚实和正确的观点和一个很好的recherche资源(我已经读过它),而且你也认识到我的实际问题可能是:“_这里唯一的问题是,特别是对于控制器,有很多依赖项并非总是被所有类的方法使用。_”。是的,你是多么正确!这让我很烦恼,但我失去了对它的关注,忙于其他重要部分(同时从我的 HMVC 中访问多个数据库服务器)。直到你让我再次意识到这一点。所以,一句话:优秀的答案!
  • 感谢您的宝贵时间!我很感激。祝你好运!
猜你喜欢
  • 2015-05-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-28
  • 1970-01-01
  • 2017-11-11
  • 2016-11-08
  • 2013-03-08
相关资源
最近更新 更多