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 design patterns sont des solutions éprouvées et réutilisables à des problèmes courants qui surviennent lors de la conception logicielle. Ce ne sont pas du code que vous copiez 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 |
|---|---|---|
| Creational | Mécanismes de création d’objets | Singleton, Factory, Builder |
| Structural | Composition de classes et d’objets | Adapter, Decorator, Composite |
| Behavioral | Interaction et responsabilités des objets | Observer, Strategy, Command |
Pourquoi apprendre les patrons de conception ? Ils fournissent un vocabulaire commun entre les 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 plus facile à maintenir.
En C++, les patrons de conception s’appuient sur les fonctionnalités de la POO que vous avez déjà apprises : l’héritage, le polymorphisme, les classes abstraites et les modèles. Au cours des prochaines leçons, vous implémenterez plusieurs patrons essentiels et comprendrez dans quels cas chacun d’eux est l’outil approprié.
Défi
FacileConstruisons un classificateur de patrons simple qui démontre ta compréhension des trois catégories de patrons de conception. Tu vas créer un système qui prend le nom d’un patron et identifie la catégorie à laquelle il appartient — Créationnelle, Structurelle ou Comportementale — accompagné d’une brève description de l’objectif de cette catégorie.
Tu organiseras ton code sur trois fichiers :
PatternCategory.h: définis une classe de base abstraite appeléePatternCategoryqui représente une catégorie de patrons de conception. Elle doit comporter :- Une méthode virtuelle pure
getName()qui renvoie le nom de la catégorie sous forme de chaîne - Une méthode virtuelle pure
getPurpose()qui renvoie une description de ce que font les patrons de cette catégorie - Un destructeur virtuel
Crée 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ée une classePatternClassifiercapable d’identifier la catégorie à laquelle appartient un patron donné.Ton classificateur doit posséder une méthode
classifyqui accepte le nom d’un patron (une chaîne) et renvoie un pointeur vers lePatternCategoryapproprié. Utilise des pointeurs intelligents (std::unique_ptr) pour la gestion de la mémoire.Le classificateur doit reconnaître les patrons suivants :
- Créationnels :
Singleton,Factory,Builder - Structurels :
Adapter,Decorator,Composite - Comportementaux :
Observer,Strategy,Command
Si le nom du patron n’est pas reconnu, renvoie
nullptr.- Créationnels :
main.cpp: lis une seule entrée : le nom d’un patron de conception.Crée un
PatternClassifieret utilise-le pour classifier le patron saisi. Si le patron est reconnu, affiche :[PatternName] is a [CategoryName] pattern Purpose: [CategoryPurpose]Si le patron n’est pas reconnu, affiche :
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 permettant de pratiquer l’héritage, le polymorphisme et les pointeurs intelligents : tous des concepts que tu maîtrises déjà. La structure en plusieurs fichiers reflète la manière 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 classifieur pour classifier le pattern en entrée
// 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