Le WordPress d'aujourd'hui, décodé pour les développeurs

Extensions

Découper une extension par fonctionnalité plutôt que par couche technique

Regrouper le code par fonctionnalité plutôt que par type technique facilite la suppression propre d'une fonctionnalité entière, sans chasse au fichier oublié.

Par Clément Hadrot • 21 février 2025 • 4 min de lecture • Aucun commentaire
Découper une extension par fonctionnalité plutôt que par couche technique

Deux façons de ranger une extension WordPress s’opposent depuis toujours : par couche technique, avec un dossier controllers, un dossier models, un dossier views ; ou par fonctionnalité, avec un dossier par capacité métier, chacun contenant son propre contrôleur, son propre modèle et sa propre vue. Les deux fonctionnent au démarrage d’un projet. Elles ne vieillissent pas de la même manière.

Prenons une extension de gestion de formations professionnelles, avec trois fonctionnalités distinctes : inscriptions, émargements et attestations. L’architecture en couches classique regroupe tout le code d’inscription, d’émargement et d’attestation dans les mêmes dossiers techniques, mélangés fonctionnellement. L’architecture par fonctionnalité regroupe au contraire tout ce qui concerne les inscriptions au même endroit, indépendamment de son rôle technique.

À quoi ressemble l’organisation en couches techniques

Voici la structure typique d’une extension organisée par couche, telle qu’on la retrouve encore fréquemment :

extension-formations/
├── controllers/
│   ├── class-inscription-controller.php
│   ├── class-emargement-controller.php
│   └── class-attestation-controller.php
├── models/
│   ├── class-inscription-model.php
│   ├── class-emargement-model.php
│   └── class-attestation-model.php
├── views/
│   ├── inscription-formulaire.php
│   ├── emargement-tableau.php
│   └── attestation-pdf.php
└── hooks/
    ├── inscription-hooks.php
    ├── emargement-hooks.php
    └── attestation-hooks.php

Chaque fonctionnalité existe, mais son code est réparti sur quatre dossiers distincts. Pour retirer entièrement la fonctionnalité « émargement », il faut identifier et supprimer un fichier dans chacun des quatre dossiers, en espérant n’en avoir oublié aucun.

À quoi ressemble l’organisation par fonctionnalité

L'essentiel à retenir : L'organisation par couche technique éparpille une fonctionnalité dans dix dossiers différents ; L'organisation par fonctionnalité regroupe tout ce qui la concerne au même endroit ; Supprimer une fonctionnalité devient supprimer un dossier, pas une chasse au fichier oublié

La même extension, réorganisée par fonctionnalité, ressemble à ceci :

extension-formations/
├── inscriptions/
│   ├── class-inscription-controller.php
│   ├── class-inscription-model.php
│   ├── vue-formulaire.php
│   └── hooks.php
├── emargements/
│   ├── class-emargement-controller.php
│   ├── class-emargement-model.php
│   ├── vue-tableau.php
│   └── hooks.php
└── attestations/
    ├── class-attestation-controller.php
    ├── class-attestation-model.php
    ├── vue-pdf.php
    └── hooks.php

Chaque dossier de fonctionnalité est autonome : il contient tout ce qui la concerne, quel que soit son rôle technique. Retirer la fonctionnalité « émargements » revient alors à supprimer un seul dossier et sa ligne de chargement dans le fichier principal de l’extension, sans avoir à parcourir mentalement quatre arborescences différentes.

Ce que cette organisation facilite concrètement

Au-delà de la suppression, plusieurs situations deviennent plus simples avec un découpage par fonctionnalité :

  • Confier une fonctionnalité entière à un développeur sans qu’il ait besoin de comprendre l’ensemble de l’extension.
  • Désactiver une fonctionnalité par condition, par exemple selon une licence ou un réglage, en chargeant ou non son dossier.
  • Retrouver rapidement tout le code lié à un bug signalé sur une fonctionnalité précise, sans naviguer entre plusieurs dossiers techniques.

Ce que cette organisation complique en contrepartie

Le découpage par fonctionnalité a un coût : le code partagé entre plusieurs fonctionnalités, comme une classe utilitaire de formatage de date ou un service d’envoi d’e-mail commun, ne trouve pas naturellement sa place dans un dossier de fonctionnalité unique. Il faut alors prévoir, dès le départ, un dossier commun ou partage clairement identifié, réservé au code réellement transverse, pour éviter qu’il ne finisse dupliqué dans chaque fonctionnalité par facilité.

Un repère simple pour trancher

La question à se poser pour chaque classe ou fonction : sert-elle une seule fonctionnalité, ou plusieurs ? Dans le premier cas, elle rejoint le dossier de la fonctionnalité concernée. Dans le second, elle rejoint le dossier commun, à condition que ce dossier reste volontairement restreint : s’il grossit au point de contenir la moitié du code de l’extension, le découpage par fonctionnalité perd son intérêt.

Comparaison directe

CritèrePar couche techniquePar fonctionnalité
Suppression d’une fonctionnalitéPlusieurs dossiers à parcourirUn seul dossier à retirer
Onboarding sur une fonctionnalitéVue d’ensemble nécessaireUn seul dossier à lire
Code réellement transverseNaturellement centraliséNécessite une convention explicite
Petites extensions (moins de 5 fichiers)SuffisantComplexité inutile

Pour une extension de moins d’une dizaine de fichiers, l’organisation par couche reste parfaitement raisonnable ; le découpage par fonctionnalité prouve sa valeur surtout au-delà, quand une fonctionnalité doit pouvoir vivre ou mourir indépendamment des autres.

En résumé

Le choix entre ces deux organisations n’est ni universel ni définitif. Il dépend surtout d’une question concrète : combien de fois, dans la vie de l’extension, faudra-t-il ajouter ou retirer une fonctionnalité entière ? Plus cette fréquence est élevée, plus le découpage par fonctionnalité rembourse rapidement l’effort de conception initial qu’il demande.

Partager :

À propos de l'auteur

Clément Hadrot

Développeur WordPress, passionné par Elementor, le FSE et l’automatisation par IA.

Voir tous ses articles

Dans la même veine

À lire aussi