Kiedy powinniśmy korzystać z repozytorium i fabryki w Magento 2?

75

Przeszedłem kilka samouczków w Magento 2 i to mnie trochę dezorientuje. Widzę, że istnieją zasadniczo dwa sposoby, dzięki którym możemy odczytywać / zapisywać podmioty gospodarcze:

Pobierać dane

Korzystanie z podejścia fabrycznego

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

Korzystanie z podejścia do repozytorium

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

Zapisz dane

Korzystanie z podejścia fabrycznego

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

Korzystanie z podejścia do repozytorium

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

Widzę również, że zarówno repozytorium, jak i klasa fabryczna mogą być wstrzykiwane za pomocą wstrzykiwania zależności. To jest mylące przynajmniej dla mnie.

Kiedy powinniśmy zastosować podejście oparte na repozytorium i podejście fabryczne? Jakiej najlepszej praktyki musimy przestrzegać?

Rajeev K Tomy
źródło
Dobry przykład użycia Factory, CollectionFactory i Repository można zobaczyć na \ Magento \ Setup \ Fixtures \ CategoryResolver
Ricardo Martins

Odpowiedzi:

72

Jeśli istnieje repozytorium i robi to, czego potrzebujesz, zawsze preferuj repozytorium.

Repozytoria są częścią umów serwisowych (są implementacjami interfejsów w Api), co oznacza, że ​​mają one służyć jako publiczny interfejs dla innych modułów.

Użyj repozytoriów do pełnego załadowania

$model->load()nie jest częścią umowy o świadczenie usług. Miałem pytanie na ten temat, możesz znaleźć przydatne odpowiedzi: Czy jest jakiś powód, aby preferować $ model-> load () nad umowami serwisowymi?

Używaj fabryk do tworzenia nowych bytów

Repozytoria nie mają metod tworzenia nowego bytu, więc w takim przypadku będziesz potrzebować fabryki. Ale skorzystaj z interfejsu fabrycznego , na przykład Magento\Catalog\Api\Data\ProductInterfaceFactory- stworzy on właściwą implementację na podstawie konfiguracji DI.

Następnie użyj repository->save()metody, aby go zapisać.

Jeśli potrzebujesz większej kontroli, skorzystaj z fabryk kolekcji

Poniższe informacje nie są oficjalną najlepszą praktyką Magento, ale obecnie repozytoria nie dają ci dokładnej kontroli nad tym, co załadować. Interfejs API kryteriów wyszukiwania pozwala definiować filtry, ale na przykład nie ma możliwości wybrania określonych atrybutów EAV ani określenia, które tabele indeksów należy dołączyć.

Są to szczegóły implementacji, ukryte przed interfejsami API umowy serwisowej, ale często te szczegóły implementacji mają znaczenie, a jeśli je zignorujesz, wydajność będzie niska. Z tego powodu, gdy tylko repozytoria mnie ograniczają, nie waham się już korzystać z podstawowych kolekcji.

Fabian Schmengler
źródło
2
Czy możesz podać przykładowy kod dotyczący wykorzystania fabryk do tworzenia nowych bytów , wyjaśnienie nie zawiera pewnych szczegółów i jest trudne do zrozumienia. Dziękuję Ci bardzo.
Key Shang
1
@Key pomaga to? devdocs.magento.com/guides/v2.2/extension-dev-guide/…
Fabian Schmengler
Dzięki. ale use the factory for the interface, such as Magento\Catalog\Api\Data\ProductInterfaceFactory - it will create the right implementation based on DI configuration.jest to punkt, którego nie mogę zrozumieć, przewodniki dla programistów nie przedstawiają InterfaceFactory , jak używać repository->save()metody do zapisywania nowych bytów? Mogę tylko użyć fabryki do zapisywania nowych bytów, a nie repozytorium.
Key Shang
@Key Shang, oznacza to, że interfejs zapewni Ci wszystkie ustawione funkcje danych, aby zapisać każdą kolumnę tabeli, więc spróbuj użyć interfejsu tam, gdzie to możliwe, aby zapisać nowe rekordy. Klasy InterfaceFactory są tworzone w ramach di: compile, dzięki czemu można je zobaczyć w folderze var / generation.
stevensagaar
@stevensagaar Dzięki, teraz rozumiem.
Key Shang
21

Dobre pytanie.

Nawet jeśli zarówno repozytoria, jak i fabryki umożliwiają nam dostęp do bytu, uważam, że powinniśmy skupić się na jego odpowiedzialności .

Z dokumentacji Magento : „Fabryki są klasami usługowymi, które tworzą instancje klas, które nie są wstrzykiwane, to znaczy modele reprezentujące jednostkę bazy danych. Tworzą warstwę abstrakcji między ObjectManager a kodem biznesowym”.

Z artykułu Alana Storma : „Obiekt repozytorium jest odpowiedzialny za odczytywanie i zapisywanie informacji o obiekcie w magazynie obiektów”

Moja interpretacja jest następująca: jeśli naszym celem jest praca z obiektami, które nie są wstrzykiwane (tak zwane „neible”), powinniśmy użyć Fabryki; jeśli skupiamy się na wyszukiwaniu / czytaniu / pisaniu obiektów w magazynie obiektów, powinniśmy użyć repozytoriów.

To jest moje idealistyczne podejście do tematu; należy pamiętać, że faktyczne wdrożenie może zmusić nas do zepsucia, jak zauważył Alan.

Cieszyć się.

Alessandro Ronchi
źródło
5

Powiedziałbym, że należy zacząć od korzystania z repozytoriów, ponieważ umożliwiają one separację kodu między odczytem / zapisem danych a logiką biznesową.

Jest na ten temat bardzo szczegółowy artykuł napisany przez Alana Storma, wyjaśniający, jak korzystać z repozytoriów, ale także analizujący wady tej nowej metody: http://alanstorm.com/magento_2_understanding_object_repositories/

Ponadto z dokumentacji Magento wyjaśniającej zalety nowego podejścia: http://devdocs.magento.com/guides/v2.0/extension-dev-guide/service-contracts/service-contracts.html

Marina Vilcea
źródło
2
Dziękuję za odpowiedź. W rzeczywistości mam tę wątpliwość na podstawie artykułu Alanstorm. :)
Rajeev K Tomy
3
Rzeczywiście, pozwala ci to myśleć, ale to chyba dobra rzecz. Nawet jeśli jest to najlepsza praktyka sugerowana przez Magento, nie oznacza to, że programiści nie mogą zadawać pytań i krytykować niektórych jej aspektów. Ponadto nadal istnieją sytuacje, które nie są objęte repozytoriami. Jednak w kontekście tworzenia rozszerzeń, które nie spowodują awarii w przyszłych wersjach przy użyciu repozytoriów, należy wziąć pod uwagę. Jestem też pewien, że będą się dalej rozwijać i oferować więcej informacji o tym, czego potrzebują programiści.
Marina Vilcea
W 100% zgadzam się z twoim komentarzem. Naprawdę mam taką nadzieję. Zobacz także odpowiedź Fabiana.
Rajeev K Tomy
Tak, widziałem :) już głosowałem na jego odpowiedź. Dzięki za świetne pytanie!
Marina Vilcea
Co więcej, czytałem gdzieś, że zastosowanie niższej metody manipulacji danymi jest odpowiednie w skryptach instalacyjnych / aktualizacyjnych $setup->updateTableRow(...);lub fabrykach, nie jestem pewien, ale wydaje mi się, że argumenty przemawiające za użyciem wyższego poziomu odnoszą się również do tego obszaru, co sądzisz?
medmek,
1

Mam nadzieję, że ta odpowiedź może pomóc również innym twórcom rozszerzeń.

Model musimy zapisać tylko przy użyciu repozytorium.

  1. Model fabryczny w Magento 2 przechowuje bardzo ograniczone dane.
  2. Z drugiej strony, model repozytorium zawiera wszystkie dane, w przypadku atrybutów eav związanych z klientem, produktami itp.
  3. Aby zapisać model, zawsze używaj Repozytorium do zapisania dowolnego obiektu, jeśli do zapisania modelu używany jest model fabryczny, usuwa on wszystkie niesystemowe atrybuty eav związane z tym podmiotem (klient, produkt itp.).

  4. Do ładowania modelu celu Repozytorium jest najlepszą opcją uzyskania modelu za pomocą metody getById ().

Będę polecał używać repozytorium tak często, jak to możliwe, specjalnie w celu zapisania modelu.

Sachin
źródło
1

Teraz ładowanie, zapisywanie, usuwanie metod (modeli) jest przestarzałe, więc możemy użyć modelu zasobów lub repozytorium.

Magento używa teraz koncepcji menedżera encji do operacji zapisywania, usuwania i ładowania.

Modele zasobów mają obiekt menedżera encji, który wykonuje te operacje.

$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();
Siva Kumar Koduru
źródło