Раздражает тонны классов для DI в конструкторах Magento 2 - есть ли лучший способ?

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?

bukart
источник

Ответы:

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.
Райан Херр
4

Я почти уверен, что вы не единственный в этом случае, и в некотором смысле я полностью понимаю, почему вы решили сделать это.

Для меня главная проблема, которую я вижу при таком подходе, заключается в том, что вы теряете одно из главных преимуществ внедрения зависимостей, которое заключается в том, чтобы сразу узнать, от чего зависит ваш класс при проверке конструктора.

Еще одним важным преимуществом Dependency Injection является то, что он облегчает тестирование кода в автоматизированной среде. В вашем случае это определенно один недостаток.

Это две причины, которые возникают, но может быть и больше.

РЕДАКТИРОВАТЬ: Я просто собираюсь добавить цитату от Алана Кента (который является частью Magento), которую вы можете найти в комментариях к этому вопросу :

Я вообще не рекомендую бросать методы в вспомогательный класс, которые не связаны между собой. Лучше иметь отдельные классы, которые представляют реальные цели. Или используйте статические методы, в этом случае нет необходимости в конструкторе (вызывающий код отвечает за получение указателей на необходимые структуры данных).

Рафаэль в цифровом пианизме
источник
Принимая во внимание, что я полностью согласен с вышеуказанными причинами. Однако, как и новичок в Magento, кажется, что есть большая кривая обучения, чтобы узнать, какие классы необходимы и зависят друг от друга, прежде чем вы сможете начать развиваться.
MackieeE