De mon point de vue une bonne manière de se représenter le modèle MVC est de réfléchir à comment fonctionne une entreprise ou une organisation quelconque.
Ensuite viennent les scenarios (user story, use case, workflow des fois je me mélange)
Exemples que j’ai à l’esprit :
aller a la préfecture déposer une demande pour faire faire son permis de conduire
(exemple bête mais parlant)
Un client (client) pousse les portes du bâtiment (application), adresse sa demande (formulaire soumis) au guichet d’accueil (routeur), puis selon le type de demande (roujours routeur), le guichet redirige le client vers le bureau compétent de 1er niveau (controller).
Ledit bureau prend en charge sa demande (document avec identifiant, photos, etc…) (POST params, files) , les valident (validateurs de formulaire) qui passe ensuite dans divers services internes (Services). Chaque travail de chaque service mis bout a bout permet de traiter la demande (accès DB via des Repositories, accès a des API) et lui renvoie le résultat attendu par la Poste (Service email et/ou API la Poste)
Qu’avons nous rencontré dans ce workflow ?
Controller :
c’est lui qui doit répondre a la requête du client. il ne doit pas contenir la logique applicative, car il n’a pas de “compétence métier”. Typiquement il n’a pas a savoir chercher de la data ou envoyer un mail.
C’est un orchestrateur qui décomposer le job : "ok alors pour répondre a la demande il y a ca + ca + ca a faire, donc je demande aux “autorités compétentes” que sont les Services.
Il sait ce qui doit etre fait, mais ne doit pas savoir comment ca doit etre faut.
Services :
chacun service “métier” fait un nombre de choses limitées, mais les fait très bien. Untel est capable d’interagir avec MailChimp, un autre gère facturation avec Stripe, un autre gère des stocks, un autre récupère des jeux de données en base, etc… etc…
Un service fait son job quelle que soit la nature de celui qui l’appelle (controller, autre service, commande console)
L’accès au données locales se fait généralement via des Repositories qui exposent des méthodes explices d’extraction de données (ex: ClientsRepo::getClientsBornIn( year ) )
Repositories :
ce sont les gardiens des données. Ils exposent des méthodes qui fournissent des jeux de données en fonction des besoins. Il les fournissent sous forme de collections de Models (et hydraté comme tu disais).
En gros ce sont des méthode qui traduisent le besoin de data en SQL.
Parfois la proximité entre Controller et Repository est si étroite que le Service semble faire double-emploi avec le Repository.
Je sais pas trop si une telle situation relève d’un bad pattern…
Models.
perso je préfère l’appellation “entité” qui m’est plus familière, mais “models” est plus normalisé.
Ce sont les classes qui représentent les tuples d’une table avec ses relations (s’il en a).
ils permettent de penser les tuples comme des objets avec des propriété et certaines facultés.
ex : un objet Produit n’est pas censé savoir s’auto persiste en base (enfin selon les patterns), mais par contre il est capable de calculer son prix HT et TTC.
Le monde objet et le monde SQL ne se comprennent pas très bien : c’est pour ca qu’un moteur ORM est la pour faire la passerelle entre les 2 mondes. Le requeteur auprès de la base c’est lui.
Donc Repositorie et ORM travaillent ensemble.
Par contre je vais pas détailler ici les diverses manières de requêter avec un ORM (raw vs DQL vs fluent)
NOTE : à la fois MVC est pas un pattern avec une nomenclature strict ET je n’ai pas parole d’évangile.
Donc si j’ai dit des trucs faux, hésitez pas a me le faire savoir.