ADR : comment faire simple quand on peut se compliquer la vie
On va parler un peut de l’Action-Domain-Responder, ou ADR pour ceux qui veulent impressionner leurs collègues de bureau ou les recruteurs en entretien. Parce qu'on sait très bien que balancer des acronymes techniques, ça fait grimper la facture plus vite qu’une Tesla qui brûle.
C’est quoi ce fameux ADR ?
Tu connais le MVC ? Eh bien ADR, c’est un peu comme le MVC mais en plus snob. En gros, quelqu'un s’est dit : "Hé, si on prenait un truc simple comme le MVC et qu'on rajoutait une couche inutile ? ».
Dans MVC, on a le controller qui joue un peu l’arbitre entre la vue et le modèle. C’est lui qui récupère les infos, les trie et décide à qui les envoyer.
Avec ADR, on s'est dit que l’arbitre, il était trop pépère, un peu trop planqué derrière son sifflet sans rien faire d'autre que distribuer le jeu. Du coup, pour le réveiller un peu, on l’a découpé en plusieurs parties pour le responsabiliser.
Maintenant, on a une Action, c'est-à-dire une fonction toute seule dans son coin, un peu comme un célibataire qui refuse de s’engager mais qui assume totalement son indépendance.
Cette Action, elle prend la requête HTTP, la démonte, la vérifie et la passe tranquillement au reste du système.
En gros, c’est elle qui encaisse les coups en première ligne, juste avant que le vrai travail ne commence.
Exemple d'Action Symfony
#[Route('/articles/{id}', name: 'article_show')]
public function __invoke(int $id, ArticleRepository $articleRepository, ArticleResponder $responder): Response
{
$article = $articleRepository->find($id);
return $responder->respond($article);
}
Tu as ensuite le Domain, ou domaine pour ceux qui sont allergiques à l'anglais (et je ne vous juge pas, on est entre nous).
Le domaine, c’est le cœur du métier, c’est le gars qui bosse vraiment, c’est lui qui fait les trucs intelligents. L'action lui balance les infos en disant : "Tiens, démerde-toi avec ça, moi j'ai pas que ça à faire, j'ai des épisodes de Severance à rattraper."
Exemple de Domain Symfony
class ArticleRepository extends ServiceEntityRepository
{
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, Article::class);
}
public function find(int $id): ?Article
{
return $this->findOneBy(['id' => $id]);
}
}
Et enfin tu as le Responder. Le responder, c’est comme le livreur Uber Eats du PHP. Il prend le résultat du domaine, il l’emballe proprement et il livre ça à l'utilisateur final.
C’est lui qui fait le beau, mais concrètement, c’est juste le gars qui fait la mise en page. C’est un peu l’équivalent PHP du stagiaire graphiste qu'on exploite sans vergogne dans toutes les agences web.
Exemple de Responder Symfony
class ArticleResponder
{
private TwigEnvironment $twig;
public function __construct(TwigEnvironment $twig)
{
$this->twig = $twig;
}
public function respond(Article $article): Response
{
return new Response(
$this->twig->render('article/show.html.twig', ['article' => $article])
);
}
}
Pourquoi choisir ADR ?
Eh bien, il paraît que c’est plus clair, plus simple et plus testable. Mais bon, entre nous, "plus simple et plus testable", c’est exactement ce que disent tous les développeurs juste avant d’écrire une usine à gaz qui nécessite trois jours de refactoring dès qu’on veut rajouter un bouton sur une page.
Mais soyons honnêtes deux secondes, l'intérêt réel d’ADR c’est surtout de pouvoir te la raconter en réunion en disant "nous avons adopté un pattern architectural moderne", histoire que tes collègues PHP qui font du SPIP3 ou du CodeIgniter aient envie de changer de métier ou de boire de l’eau de javel.
Bref, ADR c’est cool, c’est moderne, mais c’est surtout une belle manière de se rassurer sur nos capacités à réinventer la roue en PHP.