Introduction aux patrons de conception
Fait partie de la section Programmation Orientée Objet du Journey C++ de Coddy — leçon 90 sur 104.
Les design patterns (patrons de conception) sont des solutions éprouvées et réutilisables à des problèmes courants qui surviennent lors de la conception de logiciels. Ce ne sont pas des morceaux de code que vous copiez directement ; ce sont des modèles ou des plans qui décrivent comment structurer les classes et les objets pour résoudre des défis spécifiques de manière élégante.
Le concept a été popularisé par le « Gang of Four » (GoF) dans leur livre de 1994, qui répertoriait 23 modèles fondamentaux. Ces modèles sont généralement regroupés en trois catégories :
| Catégorie | Objectif | Exemples |
|---|---|---|
| Créationnels | Mécanismes de création d'objets | Singleton, Factory, Builder |
| Structurels | Composition de classes et d'objets | Adapter, Decorator, Composite |
| Comportementaux | Interaction et responsabilité des objets | Observer, Strategy, Command |
Pourquoi apprendre les patrons de conception ? Ils fournissent un vocabulaire commun aux développeurs — dire « utilisez une Factory ici » communique instantanément une idée complexe. Ils vous aident également à éviter de réinventer des solutions et rendent votre code plus flexible et facile à maintenir.
En C++, les patrons de conception exploitent les fonctionnalités de la POO que vous avez déjà apprises : l'héritage, le polymorphisme, les classes abstraites et les templates. Au cours des prochaines leçons, vous implémenterez plusieurs patrons essentiels et comprendrez quand chacun d'eux est l'outil approprié pour la tâche.
Défi
FacileConstruisons un classificateur de motifs simple qui démontre votre compréhension des trois catégories de patrons de conception. Vous allez créer un système qui prend un nom de motif et identifie à quelle catégorie il appartient — Creational, Structural, ou Behavioral — ainsi qu'une brève description de l'objectif de cette catégorie.
Vous organiserez votre code sur trois fichiers :
PatternCategory.h: Définissez une classe de base abstraite appeléePatternCategoryqui représente une catégorie de patron de conception. Elle doit avoir :- Une méthode virtuelle pure
getName()qui retourne le nom de la catégorie sous forme de chaîne de caractères - Une méthode virtuelle pure
getPurpose()qui retourne une description de ce que font les motifs de cette catégorie - Un destructeur virtuel
Ensuite, créez trois classes dérivées qui héritent de
PatternCategory:CreationalCategory— retourne le nom"Creational"et l'objectif"Object creation mechanisms"StructuralCategory— retourne le nom"Structural"et l'objectif"Class and object composition"BehavioralCategory— retourne le nom"Behavioral"et l'objectif"Object interaction and responsibility"
- Une méthode virtuelle pure
PatternClassifier.h: Créez une classePatternClassifiercapable d'identifier à quelle catégorie appartient un motif donné.Votre classificateur doit avoir une méthode
classifyqui prend un nom de motif (chaîne de caractères) et retourne un pointeur vers laPatternCategoryappropriée. Utilisez des pointeurs intelligents (std::unique_ptr) pour la gestion de la mémoire.Le classificateur doit reconnaître ces motifs :
- Creational :
Singleton,Factory,Builder - Structural :
Adapter,Decorator,Composite - Behavioral :
Observer,Strategy,Command
Si le nom du motif n'est pas reconnu, retournez
nullptr.- Creational :
main.cpp: Lisez une seule entrée — le nom d'un patron de conception.Créez un
PatternClassifieret utilisez-le pour classifier le motif d'entrée. Si le motif est reconnu, affichez :[PatternName] is a [CategoryName] pattern Purpose: [CategoryPurpose]Si le motif n'est pas reconnu, affichez :
Unknown pattern: [PatternName]
Par exemple, avec l'entrée Singleton :
Singleton is a Creational pattern
Purpose: Object creation mechanismsAvec l'entrée Observer :
Observer is a Behavioral pattern
Purpose: Object interaction and responsibilityAvec l'entrée Proxy :
Unknown pattern: ProxyCe défi renforce les trois catégories de patrons de conception tout en pratiquant l'héritage, le polymorphisme et les pointeurs intelligents — tous des concepts que vous maîtrisez déjà. La structure multi-fichiers reflète la manière dont les projets réels organisent les classes liées.
Aide-mémoire
Les patrons de conception (design patterns) sont des solutions réutilisables à des problèmes courants de conception logicielle. Ils servent de modèles pour structurer les classes et les objets, et non de code direct à copier.
Les patrons de conception sont regroupés en trois catégories principales :
| Catégorie | Objectif | Exemples |
|---|---|---|
| Création | Mécanismes de création d'objets | Singleton, Factory, Builder |
| Structure | Composition de classes et d'objets | Adapter, Decorator, Composite |
| Comportement | Interaction et responsabilité des objets | Observer, Strategy, Command |
Avantages des patrons de conception :
- Fournir un vocabulaire commun aux développeurs
- Éviter de réinventer des solutions à des problèmes courants
- Rendre le code plus flexible et maintenable
En C++, les patrons de conception exploitent les fonctionnalités de la POO, notamment l'héritage, le polymorphisme, les classes abstraites et les templates.
Essayez vous-même
#include <iostream>
#include <string>
#include "PatternClassifier.h"
int main() {
// Lire le nom du motif
std::string patternName;
std::cin >> patternName;
// TODO: Créer une instance de PatternClassifier
// TODO: Utiliser le classificateur pour classifier le motif d'entrée
// TODO: Si le motif est reconnu, afficher :
// "[PatternName] is a [CategoryName] pattern"
// "Purpose: [CategoryPurpose]"
// TODO: Si le motif n'est pas reconnu (nullptr), afficher :
// "Unknown pattern: [PatternName]"
return 0;
}
Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.
Toutes les leçons de Programmation Orientée Objet
1Fondamentaux de la POO
Fichiers externesBuild et Compilation C++Fichiers d'en-tête et Fichiers sourceEspaces de noms et PortéeIntroduction à la POO en C++Classes vs ObjetsLe pointeur 'this'Méthodes (Fonctions membres)Attributs (Membres de données)Bases des Ctors et DtorsRécapitulatif - Calculatrice simple4Propriétés de classe
Membres d'instance vs membres statiquesGetters et SettersFonctions membres constMot-clé mutableMéthodes et variables statiquesFonctions et classes amiesRécapitulatif - Gestionnaire de compte bancaire7Héritage
Héritage de baseNiveaux d'accès à l'héritageOrdre d'appel des Ctor et DtorRedéfinition de méthodesFonctions virtuelles et VTableHéritage multipleHéritage virtuelRécapitulatif - Hiérarchie des employés10Présentation de la STL
Présentation et philosophie de la STLConteneurs de la STLItérateursAlgorithmes de la STLFoncteurs et expressions lambdaRécapitulatif - Fréquence des mots13Patrons de conception, Partie 1
Introduction aux patrons de conceptionPatron SingletonFabrique & Fabrique abstraitePatron MonteurPatron ObservateurPatron Stratégie2Gestion de la mémoire
Mémoire Pile vs TasPointeurs et RéférencesMémoire dynamique (new/delete)Smart Pointers en C++RAII en C++Récapitulatif - Gestionnaire de tableaux dynamiques5Encapsulation
Spécificateurs d'accès en C++Spécificateurs d'accès en profondeurMasquage d'informationStruct vs ClassClasses imbriquées et internesRécapitulatif - Système de gestion d'étudiants8Polymorphisme
Polymorphisme : Compilation vs ExécutionSurcharge de fonctionsRetour sur les fonctions virtuellesFonctions virtuelles puresClasses abstraitesConception d'interfaces en C++Dynamic Casting & RTTIRécapitulatif - Calculateur de formes11Concepts avancés de la POO
Composition vs HéritageMixins via CRTPIdiome PimplEffacement de typeEnum Classes & Typage fortGestion des exceptions en POOHiérarchies d'exceptions personnalisées14Patrons de conception, Partie 2
Patron CommandePatron AdaptateurPatron DécorateurPatron Template MethodPatron ÉtatPatron CompositeRAII en tant que patron3Constructeurs et Destructeurs
Constructeur par défautConstructeur paramétréConstructeur de copieConstructeur de déplacementListes d'initialisation du constructeurConstructeurs déléguésAnalyse approfondie du destructeurRègle de trois / cinq / zéroRécapitulatif - Classe String6Surcharge d'opérateurs
Introduction à la surcharge d'opérateursSurcharge des opérateurs arithmétiquesSurcharge des opérateurs de comparaisonOpérateurs de fluxSurcharge de l'opérateur d'affectationSurcharge des opérateurs [] et ()Opérateurs de conversion de typeRécapitulatif - Classe Matrix9Templates
Templates de fonctionsTemplates de classesSpécialisation de templatesTemplates variadiquesBases de SFINAE & Type TraitsRécapitulatif - Conteneur générique