Ok, więc wczoraj rozmawialiśmy z innymi ludźmi ze społeczności Magento na temat bezpośredniego wykorzystania ObjectManager
klas / szablonów .
Jestem już świadomy powodów, dla których nie powinniśmy bezpośrednio używać ObjectManager, cytując Alana Kenta :
Jest kilka powodów. Kod będzie działał, ale najlepiej jest nie odwoływać się bezpośrednio do klasy ObjectManager.
- Ponieważ tak mówimy! ;-) (lepiej wyrażony jako spójny kod to dobry kod)
- W przyszłości kod może być używany z inną strukturą wstrzykiwania zależności
- Testowanie jest łatwiejsze - przekazujesz fałszywe argumenty dla wymaganej klasy, bez konieczności podawania próbnego menedżera obiektów ObjectManager
- Utrzymuje jaśniejsze zależności - oczywiste jest, od czego zależy kod za pośrednictwem listy konstruktorów, a nie ukrywanie zależności w środku kodu
- Zachęca programistów do lepszego myślenia o koncepcjach takich jak enkapsulacja i modularyzacja - jeśli konstruktor się powiększy, być może jest to znak, że kod wymaga refaktoryzacji
Z tego, co widziałem w StackExchange, wiele osób wybiera proste / krótkie / niezalecane rozwiązanie, na przykład coś takiego:
<?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);
Zamiast przechodzić przez bolesny, ale zalecany proces :
- tworzenie modułu
- deklarowanie preferencji
- wstrzykiwać zależności
- zadeklarować metodę publiczną
Jednak i tu pojawia się dylemat, podstawowe pliki Magento 2 często wywołują bezpośrednio ObjectManager . Szybki przykład można znaleźć tutaj: https://github.com/magento/magento2/blob/develop/app/code/Magento/GoogleOptimizer/Block/Adminhtml/Form.php#L57
Oto moje pytania:
- Dlaczego Magento robi to, czego od nas nie zaleca? Czy to oznacza, że istnieją przypadki, w których powinniśmy użyć
ObjectManager
bezpośrednio ? Jeśli tak, jakie to są przypadki? - Jakie są konsekwencje bezpośredniego korzystania z 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 [...]
. Dotyczy to również M2. Sprawdź także There are valid use cases
sekcję, która również tutaj dotyczy.