Quando dovremmo usare un repository e una fabbrica in Magento 2?


76

Ho seguito un paio di tutorial in Magento 2, e questo mi confonde un po '. Vedo che ci sono fondamentalmente due modi in cui possiamo leggere / scrivere entità aziendali:

Recupera dati

Utilizzando un approccio di fabbrica

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

Utilizzando un approccio al repository

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

Salvare i dati

Utilizzando un approccio di fabbrica

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

Utilizzando un approccio al repository

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

Vedo anche che è possibile iniettare sia un repository sia una classe factory usando l'iniezione delle dipendenze. Questo è confuso almeno per me.

Quando dovremmo usare un approccio al repository e un approccio factory? Qual è la migliore pratica che dobbiamo seguire?


Un buon esempio di utilizzo di Factory, CollectionFactory e Repository può essere visto su \ Magento \ Setup \ Fixtures \ CategoryResolver
Ricardo Martins

Risposte:


73

Se esiste un repository e fa ciò di cui hai bisogno, preferisci sempre il repository.

I repository fanno parte dei contratti di servizio (sono implementazioni di interfacce in Api), ciò significa che sono intesi come un'interfaccia pubblica con altri moduli.

Utilizzare i repository per il caricamento completo

$model->load()non fa parte del contratto di servizio. Ho avuto una domanda su quel particolare argomento, potresti trovare utili le risposte: c'è mai un motivo per preferire $ model-> load () rispetto ai contratti di servizio?

Usa le fabbriche per creare nuove entità

I repository non sono dotati di metodi per creare una nuova entità, quindi in quel caso avrai bisogno di una fabbrica. Ma usa la factory per l' interfaccia , come Magento\Catalog\Api\Data\ProductInterfaceFactory- creerà la giusta implementazione basata sulla configurazione DI.

Quindi utilizzare il repository->save()metodo per salvarlo.

Usa le fabbriche di raccolta se hai bisogno di più controllo

Quella che segue non è la migliore pratica ufficiale di Magento, ma attualmente i repository non ti danno il controllo preciso su cosa caricare. L'API dei criteri di ricerca consente di definire i filtri, ma ad esempio, non è possibile selezionare determinati attributi EAV o specificare quali tabelle di indici unire.

Questi sono dettagli di implementazione, nascosti dalle API del contratto di servizio, ma spesso questi dettagli di implementazione sono importanti e si ottengono scarse prestazioni se le si ignora. Per tale motivo, non appena i repository mi limitano, non esito più a utilizzare le raccolte sottostanti.


2
Potresti dare un esempio di codice sull'uso delle Fabbriche per creare nuove entità , la spiegazione manca di alcuni dettagli e è difficile da capire. Grazie mille.
Key Shang


Grazie. ma use the factory for the interface, such as Magento\Catalog\Api\Data\ProductInterfaceFactory - it will create the right implementation based on DI configuration.è il punto che non riesco a capire, le guide di sviluppo non introducono InterfaceFactory , come utilizzare il repository->save()metodo per salvare nuove entità? Posso solo usare factory per salvare nuove entità, non repository.
Key Shang

@Key Shang, significa che l'interfaccia ti fornirà tutte le funzioni di dati impostate per salvare ogni singola colonna della tabella, quindi prova a utilizzare l'interfaccia ogni volta che è possibile per salvare nuovi record. Le classi InterfaceFactory vengono create come parte di di: compilate in modo da poterle vedere nella cartella var / generation.
Stevensagaar,

@stevensagaar Grazie, ora posso capirlo.
Key Shang

21

Buona domanda.

Anche se sia i repository sia le fabbriche ci permettono di accedere a un'entità, penso che dovremmo concentrarci sulle loro responsabilità .

Dalla documentazione di Magento : "Le fabbriche sono classi di servizio che istanziano classi non iniettabili, ovvero modelli che rappresentano un'entità di database. Creano un livello di astrazione tra l'ObjectManager e il codice aziendale".

Dall'articolo di Alan Storm : "Un oggetto repository è responsabile della lettura e della scrittura delle informazioni dell'oggetto in un archivio oggetti"

La mia interpretazione è: se il nostro scopo è lavorare con oggetti non iniettabili (i cosiddetti "nuovi") dovremmo usare le Fabbriche; se il nostro focus è sulla ricerca / lettura / scrittura di oggetti all'interno di un negozio di oggetti, dovremmo usare i repository.

Questo è il mio approccio idealistico all'argomento; tieni presente che l'implementazione effettiva potrebbe costringerci a fare confusione, come sottolineato da Alan.

Godere.


5

Direi che la strada da percorrere è iniziare a utilizzare i repository in quanto consentono la separazione del codice tra lettura / scrittura dei dati e logica aziendale.

C'è un articolo molto dettagliato scritto da Alan Storm su questo, che spiega come usare i repository ma anche esaminando alcuni svantaggi di questo nuovo metodo: http://alanstorm.com/magento_2_understanding_object_repositories/

Inoltre, dalla documentazione di Magento, che spiega i vantaggi di questo nuovo approccio: http://devdocs.magento.com/guides/v2.0/extension-dev-guide/service-contracts/service-contracts.html


2
Grazie per la risposta. In realtà ho questo dubbio sulla mia testa dall'articolo di Alanstorm se stesso. :)
Rajeev K Tomy,

3
In effetti, ti lascia pensare, ma questa è probabilmente una buona cosa. Anche se questa è la migliore pratica suggerita da Magento, ciò non significa che gli sviluppatori non possano sollevare domande e criticare alcuni aspetti di essa. Inoltre, ci sono ancora situazioni che non sono coperte dai repository. Tuttavia, nel contesto della creazione di estensioni che non si interrompono nelle versioni future utilizzando i repository, devono essere considerati. Inoltre, sono sicuro che si svilupperanno ulteriormente e offriranno maggiore copertura su ciò di cui gli sviluppatori hanno bisogno.
Marina Vilcea,

Sono d'accordo al 100% con il tuo commento. Lo spero davvero. Vedi anche la risposta di Fabian.
Rajeev K Tomy,

Sì, ho visto :) già votato la sua risposta. Grazie per l'ottima domanda!
Marina Vilcea,

Inoltre, ho letto da qualche parte che l'utilizzo del metodo di manipolazione dei dati di livello inferiore è ok negli script $setup->updateTableRow(...);o nelle fabbriche di installazione / aggiornamento , non sono sicuro ma sembra che gli argomenti per l'uso di livello superiore si applichino anche a quell'area, cosa ne pensi?
Medmek,

1

Spero che questa risposta possa aiutare anche altri sviluppatori di estensioni.

Dobbiamo salvare il modello utilizzando solo il repository.

  1. Il modello di fabbrica in Magento 2 contiene dati molto limitati.
  2. D'altra parte, il modello di repository contiene tutti i dati, nel caso di attributi eav relativi a clienti, prodotti, ecc.
  3. Per salvare il modello, utilizzare sempre Repository per salvare qualsiasi entità, se si utilizza il modello factory per salvare il modello, elimina tutti gli attributi eav non di sistema relativi a tale entità (cliente, prodotto, ecc.).

  4. Ai fini del caricamento del modello, i repository sono l'opzione migliore per ottenere il modello utilizzando il metodo getById ().

Consiglierò di usare il Repository il più possibile specialmente per scopi di salvataggio del modello.


1

Ora i metodi di caricamento, salvataggio ed eliminazione (modelli) sono obsoleti, quindi possiamo usare il modello di risorsa o il repository.

Magento ora utilizza il concetto di gestione entità per le operazioni di salvataggio, eliminazione e caricamento.

I modelli di risorsa hanno oggetto gestore entità per eseguire tali operazioni.

$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();
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.