Introduction aux modèles de conception
Fait partie de la section Programmation Orientée Objet du Journey C++ de Coddy. Leçon 90 sur 104.
Les patrons de conception sont des solutions éprouvées et réutilisables à des problèmes courants qui surviennent lors de la conception logicielle. Ce n’est pas du code que l’on copie directement : ce sont des modèles ou des schémas qui décrivent comment structurer les classes et les objets pour résoudre élégamment des problèmes spécifiques.
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é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 |
Pourquoi apprendre les modèles de conception ? Ils fournissent un vocabulaire commun aux développeurs : dire « utilise une fabrique ici » communique instantanément une idée complexe. Ils t’aident également à éviter de réinventer des solutions et rendent ton code plus flexible et plus facile à maintenir.
En C++, les patrons de conception tirent parti des fonctionnalités de la POO que tu as déjà apprises : l’héritage, le polymorphisme, les classes abstraites et les modèles. Dans les prochaines leçons, tu mettras en œuvre plusieurs patrons essentiels et tu comprendras dans quels cas chacun est l’outil adapté.
Défi
FacileConstruisons un classificateur de patrons 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 patron et détermine à quelle catégorie il appartient, Créationnelle, Structurelle ou Comportementale, ainsi qu'une brève description de l'objectif de cette catégorie.
Vous organiserez votre code dans trois fichiers :
PatternCategory.h: définissez une classe de base abstraite appeléePatternCategoryqui représente une catégorie de patrons de conception. Elle doit avoir :- Une méthode virtuelle pure
getName()qui renvoie le nom de la catégorie sous forme de chaîne de caractères - Une méthode virtuelle pure
getPurpose()qui renvoie une description de ce que font les patrons de cette catégorie - Un destructeur virtuel
Créez ensuite trois classes dérivées qui héritent de
PatternCategory:CreationalCategory: renvoie le nom"Creational"et l'objectif"Object creation mechanisms"StructuralCategory: renvoie le nom"Structural"et l'objectif"Class and object composition"BehavioralCategory: renvoie le nom"Behavioral"et l'objectif"Object interaction and responsibility"
- Une méthode virtuelle pure
PatternClassifier.h: créez une classePatternClassifiercapable de déterminer à quelle catégorie appartient un patron donné.Votre classificateur doit avoir une méthode
classifyqui prend un nom de patron (chaîne de caractères) et renvoie un pointeur vers lePatternCategoryapproprié. Utilisez des pointeurs intelligents (std::unique_ptr) pour la gestion de la mémoire.Le classificateur doit reconnaître les patrons suivants :
- Créationnelle :
Singleton,Factory,Builder - Structurelle :
Adapter,Decorator,Composite - Comportementale :
Observer,Strategy,Command
Si le nom du patron n'est pas reconnu, renvoyez
nullptr.- Créationnelle :
main.cpp: lisez une seule entrée : le nom d'un patron de conception.Créez un
PatternClassifieret utilisez-le pour classer le patron saisi. Si le patron est reconnu, affichez :[PatternName] is a [CategoryName] pattern Purpose: [CategoryPurpose]Si le patron 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 votre connaissance des trois catégories de patrons de conception tout en vous faisant pratiquer l'héritage, le polymorphisme et les pointeurs intelligents : autant de concepts que vous maîtrisez déjà. La structure en plusieurs fichiers reflète la façon dont les projets réels organisent les classes associées.
Essayez vous-même
#include <iostream>
#include <string>
#include "PatternClassifier.h"
int main() {
// Lire le nom du pattern
std::string patternName;
std::cin >> patternName;
// TODO: Créer une instance de PatternClassifier
// TODO: Utiliser le classificateur pour classer le pattern saisi
// TODO: Si le pattern est reconnu, afficher :
// "[PatternName] is a [CategoryName] pattern"
// "Purpose: [CategoryPurpose]"
// TODO: Si le pattern 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 externesGénération et compilation en C++Fichiers d’en-tête et fichiers sourceEspaces de noms et portéeIntroduction à la POO en C++Classes et objetsLe pointeur « this »Méthodes (fonctions membres)Attributs (membres de données)Bases des constructeurs et destructeursRécapitulatif - Calculatrice simple4Propriétés de classe
Membres d’instance et statiquesAccesseurs et mutateursFonctions membres constMot-clé mutableMéthodes et variables statiquesFonctions et classes amiesRécapitulatif - Gestionnaire de compte bancaire7Héritage
Héritage de baseNiveaux d’accès de l’héritageOrdre d’appel des constructeurs et destructeursRedéfinition des méthodesFonctions virtuelles et VTableHéritage multipleHéritage virtuelRécapitulatif : hiérarchie des employés10Vue d’ensemble de la STL
Vue d’ensemble et philosophie de la STLConteneurs de la STLItérateursAlgorithmes de la STLFoncteurs et expressions lambdaRécapitulatif - fréquence des mots13Modèles de conception, partie 1
Introduction aux modèles de conceptionModèle SingletonFabrique et fabrique abstraiteModèle BuilderModèle ObserverModèle Strategy2Gestion de la mémoire
Mémoire de pile ou de tasPointeurs et référencesMémoire dynamique (new/delete)Pointeurs intelligents 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 de l’informationStruct vs classeClasses imbriquées et internesRécapitulatif - Système de gestion des dossiers étudiants8Polymorphisme
Polymorphisme à la compilation vs à l’exécutionSurcharge de fonctionsRetour sur les fonctions virtuellesFonctions virtuelles puresClasses abstraitesConception d’interfaces en C++Conversion dynamique et RTTIRécapitulatif - Calculateur de formes3Constructeurs et destructeurs
Constructeur par défautConstructeur paramétréConstructeur de copieConstructeur de déplacementListes d’initialisation des constructeursConstructeurs déléguésApprofondissement des destructeursRègle des trois / cinq / zéroRécapitulatif - Classe String6Surcharge des opérateurs
Introduction à la surcharge des 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 des templatesTemplates variadiquesBases de SFINAE et des traits de typesRécapitulatif - Conteneur génériqueEntraînez-vous par vous-même : Compilateur C++ en ligne