Когда мы должны использовать репозиторий и фабрику в Magento 2?


76

Я прошел через несколько уроков в 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
Рикардо Мартинс

Ответы:


73

Если есть хранилище, и оно делает то, что вам нужно, всегда предпочитайте хранилище.

Репозитории являются частью сервисных контрактов (они являются реализациями интерфейсов в 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()метод для сохранения новых объектов? Я могу использовать только фабрику для сохранения новых сущностей, а не репозиторий.
Ключ Шан

@ Ключ, это означает, что интерфейс предоставит вам все установленные функции данных для сохранения каждого столбца таблицы, поэтому старайтесь по возможности использовать интерфейс для сохранения новых записей. Классы 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. Для сохранения модели всегда используйте Repository для сохранения любой сущности. Если для сохранения модели используется заводская модель, удаляются все несистемные атрибуты 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.