Однією з найбільших змін у Magento 2 (у порівнянні із версіями 1.х) є використання патерну ін’єкцій залежностей. Через цей шаблон проектування в базі коду багато чого було змінено та було введено багато нових елементів. Сьогоднішня стаття покликана пояснити початківцям саму основу цього шаблону проектування та використання ін’єкцій залежностей в Magento 2.
Насамперед розглянемо основну ідею використання цього патерну (шаблону проектування). Виконуючи ін’єкцію залежностей, вам потрібно запитувати залежні ресурси під час створення об’єкта, замість створення ресурсів, коли вони потрібні. Це дозволить досягти ізоляції класу і незалежної розробки, так як і простого тестування через легкість згладжування необхідних об’єктів. Перш ніж продовжувати, дозвольте продемонструвати невеличкий приклад:
class A { ... public function read() { $dbh = new DatabaseConnection(); // уникайте такого $dbh->query('SELECT ...'); ... } ... }
Попередній приклад демонструє простий клас А з методом read()
. У цьому методі нам потрібен об’єкт для з’єднання з базою даних, який створюється в першому рядку методу. Це те, до чого більшість з нас звикла, і це дещо схоже на те, що використовується в Magento 1.x (фабричний патерн). Наступний приклад реалізує ту ж саму логіку, але за патерном ін’єкції залежностей:
class A { protected $_dbh; ... public function __construct(DatabaseConnection $connection) { $this->_dbh = $connection; } ... public function read() { $this->_dbh->query('SELECT ...'); ... } ... }
У цьому прикладі об’єкт з’єднання з базою даних був переданий класу А через конструктор, а не створювався в межах методу read()
. Незважаючи на те, що це не єдиний спосіб передачі залежностей об’єкту, така реалізація використовується в Magento 2. Отже, що саме це нам дає?
Клас А може бути розроблений незалежно від класу DatabaseConnection
, оскільки ми можемо завжди підробляти зв’язок для цілей розробки. Він не залежить від реалізації DatabaseConnection
і в такий спосіб набагато простіше перевірити наш код.
Одним із недоліків є те, що другий приклад коду трохи більший за перший. І це правда, для прикладу Magento\Catalog\Model\Product
має конструктор, який займає більше 50 рядків коду. Крім того, якщо ви спробуєте налагодити цей код, ви побачите, що це дуже важке завдання. На щастя, тут на допомогу приходить тестування.
Для ініціалізації таких великих об’єктів ін’єкції залежностей мають контейнер для ін’єкцій залежностей, а в Magento 2 він називається ObjectManager
. Цей контейнер відповідає за розбір та створення залежностей після створення об’єктів. Давайте розглянемо, як це працює на простому прикладі:
class A { public function __construct(B $b) { $this->_b = $b; } }
При створенні об’єкта з класу А відбувається таке:
ObjectManager->create('A')
У цих кількох кроках ObjectManager створив об’єкт із класу. Але на даний момент не будемо вважати це таким простим і уявимо собі, що в нас є декілька реалізацій класу B. Це ставить питання, яку реалізацію буде використано? І відповідь на це питання можна знайти в одному з файлів di.xml
, які розташовані в наступних місцях:
{папка_модуля}/etc/(область_коду)/di.xml
{папка_модуля}/etc/di.xml
app/etc/di/*.xml
У цих файлах ви можете знайти/вказати такі налаштування:
types
та virtualTypes
Ще одна річ, яку потрібно пояснити, — тип об’єктів для ін’єкції. У Magento 2 вони розділені на дві групи: ін’єкційні та неін’єкційні. Спочатку розглянемо неін’єкційні об’єкти. Після цього ви самі впізнаєте ін’єкційні об’єкти.
Наприклад, давайте розглянемо сторінку товару, на якій ви хочете відобразити поточний товар та деякі пов’язані товари. Якщо ви передаєте модель товару до свого контролера, спершу вам потрібно буде викликати завантаження цього товару, щоб отримати поточний товар. Але як тільки цей об’єкт буде використовуватись, де ви отримаєте інформацію про інші товари? Тож тут ми усвідомлюємо, що модель товару – це один з об’єктів, що не є ін’єкційними. Насправді, всі об’єкти, які мають певний тип ідентичності, можуть бути неін’єкційними: товари, замовлення, елементи кошика, користувачі, …
Щоб використовувати в коді неін’єкційні об’єкти, ви повинні подати запит на їх фабрику (factory). Наприклад, якщо ви намагаєтеся завантажити декілька товарів, ваш код буде залежати від фабрики товару, і через цей об’єкт ви будете викликати метод create()
з ідентифікацією товарів, які ви намагаєтеся завантажити. Проксі (proxies) призначені, головним чином, для відкладеного завантаження необов’язкових або «важких» залежностей.
От ми і розглянули коротко самі основи шаблону проектування з використанням ін’єкцій залежностей. Сподіваємось, що ця інформація дозволить вам мати певний багаж знань перед більш поглибленим вивченням цієї теми. Для цього ви можете ознайомитись із специфікацією на офіційному сайті Magento.
Сьогоднішній огляд присвячений людям, для яких важливе питання конфіденційності в Інтернеті, та хто цінує свої…
Вперше про бренд Pro Plan почули у 1986 році, коли він став частиною американської компанії…
Страх покарання гірше самого покарання (Покарання — завжди щось конкретне, і воно все ж краще,…
Якщо ви плануєте розмістити веб-сайт в мережі Інтернет, дуже важливо знайти для нього швидкий і…
Навчання за кордоном вже давно асоціюється з якісною освітою, новими можливостями та безліччю перспектив. Але…
Вибір майстра для ремонту та перетяжки меблів – завдання, яке потребує вдумливого підходу. Адже від…