Afin de maintenir une bonne architecture logicielle, il est recommandé d’utiliser les patrons de conception lorsque c’est approprié. Cet article présente comment utiliser le patron de conception nommé Repository dans le cadre d’un projet qui utilise le cadriciel Symfony avec Doctrine.
Pour bien débuter, voici quelques éléments sur les patrons de conception.
Définition du patron de conception
Patron de conception : En informatique, et plus particulièrement en développement logiciel, un patron de conception (plus souvent appelé design pattern) est un arrangement caractéristique de modules, reconnu comme bonne pratique en réponse à un problème de conception d’un logiciel. Il décrit une solution standard, utilisable dans la conception de différents logiciels.
https://fr.wikipedia.org/wiki/Patron_de_conception
« Les patrons offrent la possibilité de capitaliser un savoir précieux né du savoir-faire d’experts »
— Buschmann, 1996.
Quelques exemples de patrons de conception
Des dizaines de patrons de conception sont disponibles. En voici quelques exemples :
- MVC
- Factory
- Repository
- ActiveRecord
- …
Voici un lien vers Tutsplus.com, un très bon site qui présente ces patrons de conception accompagnés d’exemples programmés en PHP.
1 |
Coool |
http://code.tutsplus.com/series/design-patterns-in-php–cms-747
Le patron de conception nommé repository
Le patron de conception repository permet d’encapsuler les requêtes lancées à la base de données. Grâce au repository, la règle « Thin controllers, fat models » est renforcée. De plus, les méthodes développées pour un repository pourront facilement être réutilisées dans votre application. Finalement, il est plus facile de tester un repository qu’un contrôleur puisque moins de dépendances sont en jeu.
Créer un repository pour Doctrine
Afin de créer une classe repository, il faut hériter de la classe \Doctrine\ORM\EntityRepository.
Ensuite, il est possible d’ajouter des méthodes utiles pour l’application. Par exemple, une méthode qui retourne tous les commentaires des utilisateurs. Un nom significatif est sélectionné , le code est écrit et testé
/src/Acme/Bundle/ApiBundle/Entity/CommentRepository.php
1 2 3 4 5 6 7 8 9 10 11 |
<?php class CommentRepository extends EntityRepository { public function findAllComments() { return $this ->createQueryBuilder('a') ->getQuery() ->getResult() ; } } |
Les méthodes ajoutées à la classe repository doivent retourner les résultats du QueryBuilder. Le QueryBuilder est une classe qui permet la création d’une requête qui sera éventuellement lancée vers la base de données. Le langage SQL n’est pas utilisé ici, l’ORM Doctrine offre une interface compatible avec tous les SGBDR nommés DQL (Doctrine Query Language).
Voici un autre exemple pour récupérer un commentaire à partir de son identifiant :
1 2 3 4 5 6 7 8 9 10 11 12 |
<?php public function findOneComment($id) { $qb = $this->createQueryBuilder('a'); $qb->where('a.id = :id') ->setParameter('id', $id); return $qb ->getQuery() ->getResult() ; } |
Une note sur les entités Doctrine
Doctrine offre plusieurs méthodes utiles à partir des entités directement. En fait, il est possible de récupérer tous les enregistrements pour une entité avec la méthode findAll(). D’autres méthodes comme findBy(), findOneBy(),
http://doctrine-orm.readthedocs.io/projects/doctrine-orm/en/latest/reference/working-with-objects.html#querying
Même si cette solution est plus simple, il est tout de même recommandé d’encapsuler les requêtes utilisées dans un repository. Cela apporte quelques avantages :
- Permet de faire évoluer le code sans avoir modifier tous les appels de la fonction.
- Il est donc possible de modifier le comportement du repository à un endroit centralisé.
- Facilite les tests.
- Améliore l’architecture de l’application.
src/AppBundle/Entity/ProductRepository.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<?php namespace AppBundle\Entity; use Doctrine\ORM\EntityRepository; class ProductRepository extends EntityRepository { public function findAllOrderedByName() { return $this->getEntityManager() ->createQuery( 'SELECT p FROM AppBundle:Product p ORDER BY p.name ASC' ) ->getResult(); } } |
Pour plus d’information, voici un lien vers la référence officielle pour créer des repository avec Doctrine.
Utiliser un repository avec Doctrine
Une fois la classe repository créée avec les méthodes pertinentes, il est facile d’utiliser les services de ce nouveau repository. Dans un contrôleur, il suffit d’utiliser la méthode getRepository et de spécifier le nom du repository à récupérer. Par la suite, la méthode développée est appelée comme dans l’exemple suivant :
1 2 3 4 5 |
<?php $em = $this->getDoctrine()->getManager(); $entities = $em->getRepository('AcmeApiBundle:Comment')->findAllComments(); |
Tester un repository avec Doctrine
Afin de tester le repository, il est proposé de mettre en place des données de tests (fixtures) et d’utiliser PHPUnit. Bien tester le repository est essentiel afin de garantir la qualité du logiciel développé en mode Agile.
1 2 3 4 5 6 7 8 |
<?php public function testFindAllComments() { $em = $this->getDoctrine()->getManager(); $entities = $em->getRepository('AcmeApiBundle:Comment')->findAllComments(); $this->assertCount($entities, 5); ... } |
Conclusion
Utiliser le patron de conception repository dans un projet Symfony / Doctrine est une bonne pratique logicielle qui permet de mettre en place une meilleure structure et de faciliter l’exécution de tests.
Laisser un commentaire
Participez-vous à la discussion?N'hésitez pas à contribuer!