Коли ми повинні використовувати сховище та завод у Magento 2?


75

Я пройшов кілька навчальних посібників у Magento 2, і це мене трохи бентежить. Я бачу, що в основному є два способи, за допомогою яких ми можемо читати / писати суб’єкти господарювання:

Отримати дані

Використання заводського підходу

$object = $this->myFactory->create();
$object->load($myId);

Використання підходу репозиторію

$repo   = $this->myRepository();
$object = $repo->getById($myId);

Збереження даних

Використання заводського підходу

$object = $this->myFactory->create();
$object->load($myId);
$object->setData('something', 'somethingDifferent')->save();

Використання підходу репозиторію

$repo   = $this->myRepository();
$object = $repo->getById($myId);
$object->setData('something', 'somethingDifferent');
$repo->save($object);

Я також бачу, що і сховище, і заводський клас можна вводити за допомогою ін'єкції залежності. Це щонайменше для мене бентежить.

Коли ми повинні використовувати підхід сховища та заводський підхід? Якої найкращої практики нам потрібно дотримуватися?


Хороший приклад використання Factory, CollectionFactory та Repository можна побачити на \ Magento \ Setup \ Fixtures \ CategoryResolver
Рікардо Мартінс

Відповіді:


72

Якщо є сховище і воно робить те, що вам потрібно, завжди віддайте перевагу сховищу.

Репозиторії є частиною Контрактів на обслуговування (вони є реалізацією інтерфейсів в Api), це означає, що вони розуміються як публічний інтерфейс для інших модулів.

Використовуйте сховища для повного завантаження

$model->load()не є частиною договору послуги. У мене виникло запитання з цієї конкретної теми, можливо, ви знайдете відповіді корисними: чи є коли-небудь причина віддати перевагу $ model-> load () над контрактами на обслуговування?

Використовуйте Фабрики для створення нових організацій

Репозиторії не мають методів створення нової сутності, тому в цьому випадку вам знадобиться фабрика. Але використовуйте заводський інтерфейс , наприклад Magento\Catalog\Api\Data\ProductInterfaceFactory- він створить правильну реалізацію на основі конфігурації DI.

Потім використовуйте repository->save()метод, щоб зберегти його.

Використовуйте Фабрики колекції, якщо вам потрібен більше контроль

Далі не є офіційною найкращою практикою Magento, але наразі сховища не дають точного контролю над тим, що завантажувати. API критеріїв пошуку дозволяє визначати фільтри, але, наприклад, немає можливості вибрати конкретні атрибути EAV або вказати, до яких таблиць індексів долучитись.

Це деталі реалізації, приховані від API контрактів на надання послуг, але часто ці деталі реалізації мають значення, і якщо ви їх ігноруєте, ви отримаєте низьку ефективність. З цієї причини, як тільки репозиторії обмежують мене, я більше не вагаюся використовувати базові колекції.


2
Чи можете ви навести приклад коду щодо використання Фабрик для створення нових об'єктів , пояснення пропускають деякі деталі і важко зрозуміти. Дуже дякую.
Ключ Шан


Дякую. але use the factory for the interface, such as Magento\Catalog\Api\Data\ProductInterfaceFactory - it will create the right implementation based on DI configuration.суть, яку я не можу зрозуміти, посібники розробників не вводять InterfaceFactory , як використовувати repository->save()метод для збереження нових сутностей? Я можу просто використовувати фабрику для збереження нових об'єктів, а не сховища.
Ключ Шан

@Key Shang, це означає, що інтерфейс надасть вам всі задані функції даних для збереження кожного та кожного стовпця таблиці, тому спробуйте використовувати інтерфейс, де це можливо, для збереження нових записів. Класи InterfaceFactory створюються як частина di: compile, щоб ви могли бачити їх у папці var / generation.
stevensagaar

@stevensagaar Спасибі, я зараз це можу зрозуміти.
Ключ Шан

21

Гарне питання.

Навіть якщо і сховища, і фабрики дозволяють нам отримати доступ до організації, я думаю, що ми повинні зосередитись на їх відповідальності .

З документації Magento : "Фабрики - це сервісні класи, які створюють неін'єкційні класи, тобто моделі, що представляють сутність бази даних. Вони створюють шар абстракції між ObjectManager та бізнес-кодом."

З статті Алана Шторма : "Об'єкт сховища відповідає за зчитування та запис інформації про ваш об'єкт у магазин об'єктів"

Моє тлумачення: Якщо нашою метою є робота з неін'єкційними (так званими "новими") об'єктами, ми повинні використовувати Фабрики; якщо наша увага зосереджена на пошуку / читанні / записуванні об'єктів у магазині об'єктів, ми повинні використовувати Репозиторії.

Це мій ідеалістичний підхід до теми; майте на увазі, що реальна реалізація може змусити нас зіпсувати речі, на що вказував Алан.

Насолоджуйтесь.


5

Я б сказав, що вперед слід почати використовувати сховища, оскільки вони дозволяють розділити код між зчитуванням / записом даних та бізнес-логікою.

Є дуже детальна стаття, написана Аланом Штормом про це, в якій пояснюється, як використовувати сховища, а також вивчається деякі недоліки цього нового методу: http://alanstorm.com/magento_2_understanding_object_repositories/

Також з документації Magento, що пояснює переваги цього нового підходу: http://devdocs.magento.com/guides/v2.0/extension-dev-guide/service-contracts/service-contracts.html


2
дякую за відповідь. Я фактично отримую це сумнів на голову з статті про алансторму. :)
Радєєв К Томі

3
Дійсно, це залишає вас думати, але це, мабуть, гарна річ. Навіть якщо це найкраща практика, запропонована Magento, це не означає, що розробники не можуть ставити питання і критикувати деякі її аспекти. Крім того, все ще існують ситуації, які не охоплені сховищами. Однак у контексті побудови розширень, які не порушаться на майбутніх випусках із використанням сховищ, слід враховувати. Також я впевнений, що вони розвиватимуться далі і пропонують більше висвітлення того, що потрібно розробникам.
Марина Вільча

Я на 100% згоден з вашим коментарем. Я дуже сподіваюся на це. Також дивіться відповідь фабіана.
Радєєв К Томі

Так, я бачив :) вже схвалив його відповідь. Дякую за чудове запитання!
Марина Вільча

Далі я десь прочитав, що з використанням методу маніпулювання даними нижчого рівня це нормально в сценаріях встановлення / оновлення $setup->updateTableRow(...);або на заводах, я не впевнений, але здається, що аргументи щодо використання вищого рівня також застосовуються до цієї області.
medmek

1

Сподіваюся, що ця відповідь може допомогти і іншим розробникам розширень.

Нам потрібно зберегти модель лише за допомогою сховища.

  1. Заводські моделі в Magento 2 містять дуже обмежені дані.
  2. З іншого боку, модель сховища містить усі дані, якщо є атрибути EAV, пов'язані із замовником, продуктами тощо.
  3. Для збереження моделі завжди використовуйте Репозиторій, щоб зберегти будь-яку сутність, якщо для збереження моделі використовується заводська модель, вона видаляє всі несистемні атрибути eav, пов'язані з цією сутністю (клієнтом, продуктом тощо).

  4. Для завантаження цілей моделі Репозиторій є найкращим варіантом для отримання моделі за допомогою методу getById ().

Я рекомендую використовувати Репозиторій якомога більше спеціально для цілей збереження моделі.


1

Тепер методи завантаження, збереження, видалення (моделі) застарілі. Тому ми можемо використовувати модель ресурсу або сховище.

Зараз Magento використовує концепцію менеджера об'єктів для операцій збереження, видалення та завантаження.

Моделі ресурсів мають об'єкт менеджера об'єкта для виконання цих операцій.

$categoryModel = $this->_objectManager->create('\Magento\Catalog\Model\CategoryFactory')->create();        
  $categoryResource = $this->_objectManager->create('\Magento\Catalog\Model\ResourceModel\Category');        
  $categoryResource->load($categoryModel, 3);        
  echo $categoryModel->getName();
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.