Модель
У міру зростання нашого додатка ми незабаром виявляємо, що нам необхідно виконувати аналогічні операції з базою даних у різних місцях і в різних презентерах. Наприклад, отримувати найновіші опубліковані статті. Якщо ми покращимо наш застосунок, додавши до статей прапор, що вказує на стан готовності, ми також повинні пройтися всіма місцями в нашому застосунку та додати умову where, щоб переконатися, що вибираються тільки готові статті.
На цьому етапі прямої роботи з базою даних стає недостатньо, і розумніше буде допомогти собі новою функцією, що повертає опубліковані статті. І коли пізніше ми додамо ще один пункт (наприклад, не відображати статті з майбутньою датою), ми редагуватимемо наш код тільки в одному місці.
Ми помістимо функцію в клас PostFacade
і назвемо її
getPublicArticles()
.
Створимо наш клас моделі PostFacade
у директорії app/Model/
, щоб
подбати про наші статті. Давайте помістимо його у файл
PostFacade.php
.
У цьому класі ми передаємо базу даних Explorer. Це дасть змогу використовувати можливості DI-контейнера.
Перейдемо до файлу HomePresenter.php
, який ми відредагуємо так, щоб
позбутися залежності від Nette\Database\Explorer
, замінивши її новою
залежністю від нашого створеного класу.
У секції use
ми використовуємо App\Model\PostFacade
. Таким чином
можна скоротити наш PHP-код тільки до PostFacade (не бійтеся, він працює
навіть у коментарях, і ваша розумна IDE повинна бути в змозі впоратися
з цим).
Залишився останній крок – навчити DI-контейнер створювати цей об'єкт.
Зазвичай це робиться шляхом додавання пункту до файлу
config/services.neon
у секції services
із зазначенням повного імені
класу та параметрів конструктора. Це, так би мовити, реєструє його, і
об'єкт потім називається сервіс. Завдяки деякій магії, яка
називається autowiring, нам зазвичай не потрібно
вказувати параметри конструктора, оскільки DI розпізнає їх і передає
автоматично. Таким чином, достатньо просто вказати ім'я класу:
Однак, додавати цей рядок також не обов'язково. У секції search
на
початку services.neon
визначено, що всі класи, які закінчуються на
-Facade
або -Factory
, шукатимуться DI автоматично, що також
стосується і PostFacade
.
Підіб'ємо підсумок
Клас PostFacade
запитує Nette\Database\Explorer
у конструкторі, і
оскільки цей клас зареєстрований у контейнері DI, контейнер створює цей
екземпляр і передає його. DI таким чином створює для нас екземпляр PostFacade
і передає його в конструкторі класу HomePresenter, який його запросив. Свого
роду матрьошка коду. :) Усі компоненти запитують тільки те, що їм
потрібно, і їх не хвилює, де і як це буде створено. Створенням
займається DI-контейнер.
Детальніше про впровадження залежностей можна прочитати тут, а про конфігурацію – тут