Ok, ayer tuvimos una gran conversación con otras personas de la comunidad de Magento sobre el uso directo de las ObjectManager
clases / plantillas .
Ya estoy al tanto de las razones por las que no deberíamos usar ObjectManager directamente, citando a Alan Kent :
Hay varias razones. El código funcionará, pero es una buena práctica no hacer referencia a la clase ObjectManager directamente.
- ¡Porque nosotros lo decimos! ;-) (mejor expresado como código consistente es un buen código)
- El código podría usarse con un marco de inyección de dependencia diferente en el futuro
- La prueba es más fácil : pasa argumentos simulados para la clase requerida, sin tener que proporcionar un ObjectManager simulado
- Mantiene las dependencias más claras : es obvio de qué depende el código a través de la lista de constructores, en lugar de tener dependencias ocultas en el medio del código
- Alienta a los programadores a pensar mejor en conceptos como la encapsulación y la modularización : si el constructor crece, tal vez sea una señal de que el código necesita refactorización
Por lo que he visto en StackExchange, muchas personas tienden a buscar la solución fácil / corta / no recomendada, por ejemplo algo como esto:
<?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);
En lugar de pasar por el doloroso pero recomendado proceso de:
- creando un módulo
- declarando preferencias
- inyectar dependencias
- declarar un método público
Sin embargo, y aquí viene el dilema, los archivos principales de Magento 2 a menudo llaman directamente al ObjectManager . Puede encontrar un ejemplo rápido aquí: https://github.com/magento/magento2/blob/develop/app/code/Magento/GoogleOptimizer/Block/Adminhtml/Form.php#L57
Asi que aqui están mis preguntas:
- ¿Por qué Magento hace lo que nos recomiendan que no hagamos? ¿Eso significa que hay algunos casos en los que deberíamos usar el
ObjectManager
directamente ? Si es así, ¿cuáles son esos casos? - ¿Cuáles son las consecuencias de usar ObjectManager directamente ?
The intent of zend-servicemanager is for use as an Inversion of Control container. It was never intended as a general purpose service locator [...]
. Lo cual se aplica también a M2. También revise la There are valid use cases
sección, que, nuevamente, se aplica aquí también.