Итак, вчера у нас была большая беседа с другими людьми из сообщества Magento относительно прямого использования ObjectManager
в классах / шаблонах .
Мне уже известны причины, по которым мы не должны использовать ObjectManager напрямую, цитируя Алана Кента :
Есть несколько причин. Код будет работать, но лучше не ссылаться на класс ObjectManager напрямую.
- Потому что мы так говорим! ;-) (лучше выражать как непротиворечивый код - хороший код)
- Код может быть использован с другой структурой внедрения зависимостей в будущем
- Тестирование проще - вы передаете фиктивные аргументы для требуемого класса, не предоставляя фиктивный ObjectManager
- Это делает ясность зависимостей - очевидно, от чего зависит код через список конструкторов, вместо того, чтобы скрывать зависимости в середине кода
- Это побуждает программистов лучше продумывать такие понятия, как инкапсуляция и модульность - если конструктор становится большим, возможно, это знак того, что код нуждается в рефакторинге
Из того, что я видел в StackExchange, многие люди склонны выбирать простое / короткое / не рекомендуемое решение, например, что-то вроде этого:
<?php
//Get Object Manager Instance
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
//Load product by product id
$product = $objectManager->create('Magento\Catalog\Model\Product')->load($id);
Вместо того, чтобы пройти болезненный, но рекомендуемый процесс :
- создание модуля
- декларирование предпочтений
- вводить зависимости
- объявить публичный метод
Однако, здесь возникает дилемма: файлы ядра Magento 2 часто вызывают ObjectManager напрямую . Быстрый пример можно найти здесь: https://github.com/magento/magento2/blob/develop/app/code/Magento/GoogleOptimizer/Block/Adminhtml/Form.php#L57
Итак, вот мои вопросы:
- Почему Magento делает то, что они рекомендуют нам не делать? Означает ли это, что в некоторых случаях мы должны использовать
ObjectManager
напрямую ? Если так, то каковы эти случаи? - Каковы последствия использования ObjectManager напрямую ?
The intent of zend-servicemanager is for use as an Inversion of Control container. It was never intended as a general purpose service locator [...]
. Что касается и М2 тоже. Также проверьте There are valid use cases
раздел, который, опять же, применяется и здесь.