Quand utiliser un référentiel et une usine dans Magento 2?


76

J'ai suivi quelques tutoriels dans Magento 2 et cela me laisse un peu perplexe. Je peux voir qu’il existe essentiellement deux moyens de lire / écrire des entités commerciales:

Récupérer des données

Utiliser une approche d'usine

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

Utiliser une approche de référentiel

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

Enregistrer des données

Utiliser une approche d'usine

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

Utiliser une approche de référentiel

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

Je peux également voir qu’un référentiel et une classe d’usine peuvent être injectés à l’aide de l’injection de dépendance. C'est déroutant au moins pour moi.

Quand devrions-nous utiliser une approche de référentiel et une approche d'usine? Quelle est la meilleure pratique à suivre?


Un bon exemple d'utilisation de Factory, CollectionFactory et Repository peut être vu sur \ Magento \ Setup \ Fixtures \ CategoryResolver
Ricardo Martins

Réponses:


73

S'il existe un référentiel et qu'il répond à vos besoins, préférez-le toujours.

Les référentiels font partie des contrats de service (ce sont des implémentations d'interfaces dans Api), cela signifie qu'ils sont conçus comme une interface publique avec d'autres modules.

Utiliser des référentiels pour un chargement complet

$model->load()ne fait pas partie du contrat de service. J'avais une question sur ce sujet particulier, vous pourriez trouver les réponses utiles: y a-t-il jamais une raison de préférer $ model-> load () aux contrats de service?

Utiliser des usines pour créer de nouvelles entités

Les référentiels ne sont pas fournis avec des méthodes permettant de créer une nouvelle entité. Dans ce cas, vous aurez besoin d'une fabrique. Mais utilisez l’usine pour l’ interface , par exemple Magento\Catalog\Api\Data\ProductInterfaceFactory- cela créera la bonne implémentation en fonction de la configuration DI.

Ensuite, utilisez la repository->save()méthode pour le sauvegarder.

Utilisez les usines de collecte si vous avez besoin de plus de contrôle

Ce qui suit n’est pas la meilleure pratique officielle de Magento, mais pour l’instant, les référentiels ne vous permettent pas de contrôler avec précision le contenu à charger. L'API de critères de recherche vous permet de définir des filtres, mais par exemple, il est impossible de sélectionner des attributs EAV particuliers ou de spécifier les tables d'index à joindre.

Ce sont des détails d'implémentation, cachés des API de contrat de service, mais souvent, ces détails d'implémentation importent et vous obtenez de mauvaises performances si vous les ignorez. Pour cette raison, dès que les dépôts me limitent, je n'hésite plus à utiliser les collections sous-jacentes.


2
Pourriez-vous donner un exemple de code sur l' utilisation des usines pour créer de nouvelles entités , l'explication manque certains détails et est difficile à comprendre. Merci beaucoup.
Clé Shang


Merci. mais use the factory for the interface, such as Magento\Catalog\Api\Data\ProductInterfaceFactory - it will create the right implementation based on DI configuration.c’est le point que je ne peux pas comprendre, les guides de développement n’introduisent pas InterfaceFactory , comment utiliser la repository->save()méthode pour enregistrer de nouvelles entités? Je ne peux utiliser que la fabrique pour sauvegarder de nouvelles entités, pas un référentiel.
Clé Shang

@Key Shang, cela signifie que l'interface vous donnera toutes les fonctions de données définies pour enregistrer chaque colonne de la table. Essayez donc d'utiliser l'interface autant que possible pour sauvegarder de nouveaux enregistrements. Les classes InterfaceFactory sont créées dans le cadre de di: compile afin que vous puissiez les voir dans le dossier var / generation.
stevensagaar

@stevensagaar Merci, je peux le comprendre maintenant.
Clé Shang

21

Bonne question.

Même si les dépôts et les usines nous permettent d'accéder à une entité, je pense que nous devrions nous concentrer sur leur responsabilité .

Dans la documentation Magento : "Les factories sont des classes de service qui instancient des classes non injectables, c'est-à-dire des modèles qui représentent une entité de base de données. Elles créent une couche d'abstraction entre ObjectManager et le code de l'entreprise."

Extrait de l'article d'Alan Storm : "Un objet de référentiel est responsable de la lecture et de l'écriture de ses informations d'objet dans un magasin d'objets"

Mon interprétation est la suivante: si notre objectif est de travailler avec des objets non-injectables (appelés "nouveaux"), nous devrions utiliser Factories; si notre objectif est de rechercher / lire / écrire des objets dans un magasin d'objets, nous devrions utiliser des référentiels.

C’est mon approche idéaliste du sujet; N'oubliez pas que la mise en œuvre réelle peut nous obliger à tout gâcher, comme l'a souligné Alan.

Prendre plaisir.


5

Je dirais que la voie à suivre consiste à commencer à utiliser des référentiels car ils permettent la séparation des codes entre la lecture / écriture de données et la logique métier.

Alan Storm a écrit un article très détaillé à ce sujet, expliquant comment utiliser les référentiels, mais aussi quelques inconvénients de cette nouvelle méthode: http://alanstorm.com/magento_2_understanding_object_repositories/

En outre, dans la documentation Magento, expliquant les avantages de cette nouvelle approche: http://devdocs.magento.com/guides/v2.0/extension-dev-guide/service-contracts/service-contracts.html


2
Merci d'avoir répondu. Ce doute sur ma tête provient de l'article d'Alanstorm lui-même. :)
Rajeev K Tomy

3
En effet, cela vous laisse penser, mais c'est probablement une bonne chose. Même si ceci est la meilleure pratique suggérée par Magento, cela ne signifie pas que les développeurs ne peuvent pas poser de questions et en critiquer certains aspects. En outre, il existe encore des situations qui ne sont pas couvertes par les référentiels. Cependant, dans le contexte de la construction d'extensions qui ne se briseront pas sur les versions futures en utilisant des référentiels devraient être considérées De plus, je suis sûr qu'ils vont continuer à se développer et à mieux couvrir les besoins des développeurs.
Marina Vilcea

Je suis 100% d'accord avec votre commentaire. J'espère vraiment. Voir aussi la réponse de Fabian.
Rajeev K Tomy

Oui, j'ai vu :) déjà voté sa réponse. Merci pour la bonne question!
Marina Vilcea

De plus, j’ai lu quelque part que l’utilisation de la méthode de manipulation de données de bas niveau est acceptable dans les scripts d’installation / de mise à niveau $setup->updateTableRow(...);ou les usines. Je ne suis pas sûr, mais il semble que les arguments en faveur de l’utilisation du niveau supérieur s’appliquent également à cette zone. Qu'en pensez-vous?
medmek

1

J'espère que cette réponse pourrait également aider d'autres développeurs d'extensions.

Nous devons enregistrer le modèle en utilisant uniquement le référentiel.

  1. Le modèle d'usine dans Magento 2 contient des données très limitées.
  2. D'autre part, le modèle de référentiel contient toutes les données, dans le cas d'attributs eav liés au client, aux produits, etc.
  3. Pour enregistrer le modèle, utilisez toujours Repository pour enregistrer toute entité. Si le modèle d'usine est utilisé pour enregistrer le modèle, il supprime tous les attributs non système liés à cette entité (client, produit, etc.).

  4. Pour le chargement du modèle, le référentiel est la meilleure option pour obtenir un modèle à l'aide de la méthode getById ().

Je recommanderai d'utiliser autant que possible le référentiel spécialement à des fins de sauvegarde de modèle.


1

Maintenant, charger, enregistrer, supprimer des méthodes (modèles) sont obsolètes. Nous pouvons donc utiliser un modèle de ressource ou un référentiel.

Magento utilise maintenant le concept de gestionnaire d'entités pour les opérations de sauvegarde, de suppression et de chargement.

Les modèles de ressources ont un objet de gestionnaire d'entités pour effectuer ces opérations.

$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();
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.