Magento 2的构造函数中大量的DI类被烦恼-有更好的方法吗?


8

这时,我很讨厌在我的模块中像下面一样编写类似的构造函数。

public function __construct(
    \Magento\Framework\Model\Context $context,
    \Magento\Framework\Registry $registry,

    /* ... */

    \Foo\Bar\Model\Baz $baz,

    /* ... */

    \Magento\Framework\Model\ResourceModel\AbstractResource $resource = null,
    \Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null,
    array $data = []
) {
    $this->registry = $registry;

    /* ... */

    $this->baz = $baz;

    /* ... */

    /* some awesome stuff */
}

在许多很多情况下,我在模块中都需要相同类的实例。

所以我在问自己,是否可以使用一个或两个提供必要类的中央帮助程序类而不是在每个构造函数中都定义它们,这是一种可接受的方法。

这意味着这样的模式:

助手类

namespace Foo\Bar\Helper

class Main
{
    protected $baz;



    public function __construct(
        \Magento\Framework\Model\Context $context,
        \Magento\Framework\Registry $registry,

        /* ... */

        \Foo\Bar\Model\Baz $baz,

        /* ... */
    ) {
        $this->registry = $registry;

        /* ... */

        $this->baz = $baz;

        /* ... */

        /* some awesome stuff */
    }



    public function getBazInstance()
    {
        return $this->baz;
    }
}

较短的构造函数

public function __construct(

    \Foo\Bar\Helper\Main $mainHelper,

    \Magento\Framework\Model\ResourceModel\AbstractResource $resource = null,
    \Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null,
    array $data = []
) {
    $this->mainHelper = $mainHelper;

    /* some awesome stuff */
}

在这一点上,我不确定将来是否需要应对这种结构所带来的巨大不利影响。这是减少DI定义数量的可接受方法吗?

Answers:


7

检出\Magento\Framework\Model\Context,在您的示例中引用。您所描述的正是它所做的。Magento Context在整个内核中使用相似的对象来缩短DI列表。

唯一要记住的是,这不应被用来掩盖糟糕的架构决策。您应该考虑是否真的需要“整个模块”中的每个类,如果是这样,是否还有另一种组织代码的替代方法可以更好地实现同一目标。引入意外的性能问题很容易。


很好,是的。。。它不能用来“躲开糟糕的架构决策”。我最大的观点是,我不得不使用Context类(我自己和核心的帮助者)来帮助您完成我所说的那样的帮助者,我只是不确定。thx 4建议
bukart

因此,用通俗易懂的术语讲,Context类是涵盖Magento整个部分的Magento类吗?即类别上下文,将有助于管理类别的添加/编辑/删除/视图,而无需导入多个类来执行相同的操作?
MackieeE

@MackieeE不,不完全是。它们包含了您要查看的给定类的Magento的某些依赖项。它们通常是相当抽象的/沿继承链延伸的,而不是特定于特定的最终类(例如Category)。如果您看一下\Magento\Catalog\Model\Category,您会发现它包括了\Magento\Framework\Model\Context我提到的内容-实际上,类别一无所有。您正在寻找存储库-来看看\Magento\Catalog\Api\CategoryRepositoryInterface
Ryan Hoerr

4

我很确定您不是这种情况下的唯一一个人,从某种程度上我完全理解您为什么考虑这样做。

对我来说,我看到的这种方法的主要问题是,您失去了依赖注入的主要好处之一,那就是在检查构造函数时立即知道您的类依赖什么。

依赖注入的另一个重要好处是,它使代码更易于在自动化框架中进行测试。在您的情况下,这绝对是一个缺点。

这是出现的两个原因,但可能还有更多原因。

编辑:我只是要添加一个引用来自艾伦·肯特(他是Magento的一部分)的报价,您可以在这个问题的评论中找到:

我通常不鼓励将不相关的方法投掷到帮助程序类中。最好有单独的代表实际目的的类。或使用静态方法,在这种情况下,不需要构造函数(调用代码负责获取所需数据结构的句柄)。


鉴于我完全同意上述原因。但是,作为我自己的Magento新手-在开始开发之前,似乎有很大的学习曲线可以学习需要哪些类并相互依赖。
MackieeE
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.