Choisir un motif d'accès aux données
2.5.x ✅ 4.0.x ✅
Quel motif dois-je utiliser ? Cet arbre de décision vous aide à choisir entre les gestionnaires directs, le motif Repository, la couche Service et CQRS.
Arbre de décision rapide
Section intitulée « Arbre de décision rapide »flowchart TD START([Start Here]) --> Q1{How complex is<br/>your module?}
Q1 -->|Simple CRUD<br/>1-3 entities| Q2{Need testing<br/>or mocking?} Q1 -->|Moderate<br/>4-10 entities| Q3{Multiple data<br/>sources?} Q1 -->|Complex<br/>10+ entities| Q4{High traffic or<br/>read/write asymmetry?}
Q2 -->|No| HANDLER[✅ Direct Handler] Q2 -->|Yes| REPO[✅ Repository Pattern]
Q3 -->|No, just DB| REPO Q3 -->|Yes, APIs/cache| SERVICE[✅ Service Layer]
Q4 -->|No| SERVICE Q4 -->|Yes, need<br/>separate scaling| CQRS[✅ CQRS Pattern]
HANDLER --> DONE([Choose Pattern]) REPO --> DONE SERVICE --> DONE CQRS --> DONE
style HANDLER fill:#c8e6c9,stroke:#2e7d32 style REPO fill:#bbdefb,stroke:#1565c0 style SERVICE fill:#fff9c4,stroke:#f9a825 style CQRS fill:#ffcdd2,stroke:#c62828Comparaison des motifs
Section intitulée « Comparaison des motifs »| Critères | Gestionnaire direct | Repository | Couche Service | CQRS |
|---|---|---|---|---|
| Complexité | ⭐ | ⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
| Testabilité | ❌ Difficile | ✅ Bon | ✅ Excellent | ✅ Excellent |
| Flexibilité | ❌ Faible | ✅ Moyen | ✅ Élevé | ✅ Très élevé |
| XOOPS 2.5.x | ✅ Natif | ✅ Fonctionne | ✅ Fonctionne | ⚠️ Complexe |
| XOOPS 4.0 | ⚠️ Déprécié | ✅ Recommandé | ✅ Recommandé | ✅ Pour la mise à l’échelle |
| Taille de l’équipe | 1 dev | 1-3 devs | 2-5 devs | 5+ devs |
| Maintenance | ❌ Plus élevée | ✅ Modérée | ✅ Plus basse | ⚠️ Nécessite l’expertise |
Quand utiliser chaque motif
Section intitulée « Quand utiliser chaque motif »✅ Gestionnaire direct (XoopsPersistableObjectHandler)
Section intitulée « ✅ Gestionnaire direct (XoopsPersistableObjectHandler) »Meilleur pour : Modules simples, prototypes rapides, apprentissage de XOOPS
// Simple et direct - bon pour les petits modules$handler = xoops_getModuleHandler('article', 'news');$articles = $handler->getObjects(new Criteria('status', 1));Choisir ceci quand :
- Construire un module simple avec 1-3 tables de base de données
- Créer un prototype rapide
- Vous êtes le seul développeur et n’avez pas besoin de tests
- Le module ne croîtra pas significativement
Limitations :
- Difficile à tester unitairement (dépendance globale)
- Couplage serré à la couche de base de données XOOPS
- La logique métier a tendance à s’échapper dans les contrôleurs
✅ Motif Repository
Section intitulée « ✅ Motif Repository »Meilleur pour : La plupart des modules, les équipes voulant la testabilité
// L'abstraction permet de simuler pour les testsinterface ArticleRepositoryInterface { public function findPublished(): array; public function save(Article $article): void;}
class XoopsArticleRepository implements ArticleRepositoryInterface { private $handler;
public function __construct() { $this->handler = xoops_getModuleHandler('article', 'news'); }
public function findPublished(): array { return $this->handler->getObjects(new Criteria('status', 1)); }}Choisir ceci quand :
- Vous voulez écrire des tests unitaires
- Vous pourriez changer les sources de données plus tard (DB → API)
- Travailler avec 2+ développeurs
- Construire des modules pour la distribution
Chemin de mise à jour : C’est le motif recommandé pour la préparation XOOPS 4.0.
✅ Couche Service
Section intitulée « ✅ Couche Service »Meilleur pour : Modules avec logique métier complexe
// Le service coordonne plusieurs dépôts et contient les règles métierclass ArticlePublicationService { public function __construct( private ArticleRepositoryInterface $articles, private NotificationServiceInterface $notifications, private CacheInterface $cache ) {}
public function publish(int $articleId): void { $article = $this->articles->find($articleId); $article->setStatus('published'); $article->setPublishedAt(new DateTime());
$this->articles->save($article); $this->notifications->notifySubscribers($article); $this->cache->invalidate("article:{$articleId}"); }}Choisir ceci quand :
- Les opérations couvrent plusieurs sources de données
- Les règles métier sont complexes
- Vous avez besoin de la gestion des transactions
- Plusieurs parties de l’application font la même chose
Chemin de mise à jour : Combiner avec Repository pour une architecture robuste.
⚠️ CQRS (Command Query Responsibility Segregation)
Section intitulée « ⚠️ CQRS (Command Query Responsibility Segregation) »Meilleur pour : Modules haute performance avec asymétrie lecture/écriture
// Les commandes modifient l'étatclass PublishArticleCommand { public function __construct( public readonly int $articleId, public readonly int $publisherId ) {}}
// Les requêtes lisent l'état (peuvent utiliser des modèles de lecture dénormalisés)class GetPublishedArticlesQuery { public function __construct( public readonly int $limit = 10 ) {}}Choisir ceci quand :
- Les lectures surpassent largement les écritures (100:1 ou plus)
- Vous avez besoin de mise à l’échelle différente pour les lectures vs écritures
- Exigences complexes en matière de rapports/analyses
- L’approvisionnement en événements bénéficierait à votre domaine
Avertissement : CQRS ajoute une complexité significative. La plupart des modules XOOPS n’en ont pas besoin.
Chemin de mise à niveau recommandé
Section intitulée « Chemin de mise à niveau recommandé »flowchart LR H0["Gestionnaire direct<br/>(XOOPS 2.5.x aujourd'hui)"] R["Motif Repository<br/>(Prochaine étape recommandée)"] S["+ Couche Service<br/>(Quand la complexité croît)"] C["+ CQRS<br/>(Seulement si la mise à l'échelle nécessite)"]
H0 -->|"Étape 1"| R R -->|"Étape 2"| S S -->|"Étape 3<br/>(rare)"| C
style H0 fill:#ffcdd2 style R fill:#c8e6c9 style S fill:#bbdefb style C fill:#fff9c4Étape 1 : Envelopper les gestionnaires dans les dépôts (2-4 heures)
Section intitulée « Étape 1 : Envelopper les gestionnaires dans les dépôts (2-4 heures) »- Créer une interface pour vos besoins d’accès aux données
- L’implémenter à l’aide du gestionnaire existant
- Injecter le référentiel au lieu d’appeler
xoops_getModuleHandler()directement
Étape 2 : Ajouter la couche Service si nécessaire (1-2 jours)
Section intitulée « Étape 2 : Ajouter la couche Service si nécessaire (1-2 jours) »- Quand la logique métier apparaît dans les contrôleurs, extraire vers un Service
- Le service utilise les dépôts, pas les gestionnaires directement
- Les contrôleurs deviennent fins (routage → service → réponse)
Étape 3 : Envisager CQRS uniquement si (rare)
Section intitulée « Étape 3 : Envisager CQRS uniquement si (rare) »- Vous avez des millions de lectures par jour
- Les modèles de lecture et d’écriture sont considérablement différents
- Vous avez besoin d’approvisionnement en événements pour les pistes d’audit
- Vous avez une équipe expérimentée avec CQRS
Carte de référence rapide
Section intitulée « Carte de référence rapide »| Question | Réponse |
|---|---|
| ”Je dois juste sauvegarder/charger les données” | Gestionnaire direct |
| ”Je veux écrire des tests” | Motif Repository |
| ”J’ai des règles métier complexes” | Couche Service |
| ”Je dois mettre à l’échelle les lectures séparément” | CQRS |
| ”Je me prépare pour XOOPS 4.0” | Repository + Couche Service |
Documentation connexe
Section intitulée « Documentation connexe »- Guide du motif Repository
- Guide du motif Couche Service
- Guide du motif CQRS (avancé)
- Contrat du mode hybride
#patterns #data-access #decision-tree #best-practices #xoops