Modèle Builder
Fait partie de la section Programmation Orientée Objet du Journey C++ de Coddy. Leçon 93 sur 104.
Le pattern Builder sépare la construction d’un objet complexe de sa représentation, ce qui vous permet de créer différentes configurations étape par étape. Cela est particulièrement utile lorsqu’un objet possède de nombreux paramètres facultatifs ou nécessite une séquence de construction spécifique.
Au lieu d’un constructeur avec de nombreux paramètres (qui devient déroutant), le Builder fournit des méthodes claires et nommées pour chaque option de configuration :
#include <iostream>
#include <string>
class Pizza {
public:
std::string dough;
std::string sauce;
std::string topping;
bool cheese;
void describe() const {
std::cout << dough << " dough, " << sauce << " sauce, "
<< topping << (cheese ? ", with cheese" : "") << "\n";
}
};
class PizzaBuilder {
private:
Pizza pizza;
public:
PizzaBuilder& setDough(const std::string& d) {
pizza.dough = d;
return *this;
}
PizzaBuilder& setSauce(const std::string& s) {
pizza.sauce = s;
return *this;
}
PizzaBuilder& setTopping(const std::string& t) {
pizza.topping = t;
return *this;
}
PizzaBuilder& addCheese() {
pizza.cheese = true;
return *this;
}
Pizza build() { return pizza; }
};
int main() {
Pizza margherita = PizzaBuilder()
.setDough("thin")
.setSauce("tomato")
.setTopping("basil")
.addCheese()
.build();
margherita.describe();
}Chaque méthode setter renvoie une référence au générateur (return *this), ce qui permet de chaîner les méthodes pour obtenir une interface fluide. La méthode build() finalise et renvoie l’objet construit.
Utilisez Builder lorsque vous construisez des objets comportant de nombreux composants facultatifs, lorsque vous souhaitez un code de construction lisible ou lorsque le même processus de construction doit créer différentes représentations.
Défi
FacileConstruisons un système de construction d'ordinateurs qui permet aux utilisateurs de configurer des PC personnalisés étape par étape. C'est un scénario idéal pour le patron Builder : les ordinateurs comportent de nombreux composants facultatifs, et nous voulons disposer d'une manière claire et lisible d'assembler différentes configurations.
Vous organiserez votre code dans trois fichiers :
Computer.h: définissez la classe produit qui représente un ordinateur entièrement configuré.Votre classe
Computerdoit stocker ces composants en tant que membres privés :cpu(chaîne de caractères),ram(chaîne de caractères),storage(chaîne de caractères),gpu(chaîne de caractères) ethasWifi(booléen). InitialisezhasWifiàfalseet les chaînes à une valeur vide par défaut.Ajoutez une méthode publique appelée
showSpecs()qui affiche la configuration de l'ordinateur. Pour chaque composant qui a été défini (chaîne non vide), affichez-le sur sa propre ligne. La capacité Wi-Fi ne doit être affichée que si elle est activée.ComputerBuilder.h: créez la classe builder qui construit les ordinateurs avec une interface fluide.Votre classe
ComputerBuilderdoit posséder un membre privéComputerqu'elle construit progressivement. Implémentez ces méthodes, chacune retournant une référence vers le builder afin de permettre le chaînage des méthodes :setCPU(const std::string& cpu)setRAM(const std::string& ram)setStorage(const std::string& storage)setGPU(const std::string& gpu)addWifi(): active la capacité Wi-Fi
Implémentez également une méthode
build()qui retourne l'objetComputerterminé et réinitialise le builder pour permettre sa réutilisation.main.cpp: assemblez tous les éléments pour construire un ordinateur personnalisé.Lisez quatre entrées :
- Modèle du CPU (chaîne de caractères)
- Caractéristiques de la RAM (chaîne de caractères)
- Caractéristiques du stockage (chaîne de caractères)
- Indiquer s'il faut inclure le Wi-Fi :
yesouno
Utilisez
ComputerBuilderpour construire un ordinateur avec le CPU, la RAM et le stockage fournis. Si l'entrée Wi-Fi estyes, appelez égalementaddWifi(). Notez qu'aucun GPU n'est spécifié dans cette configuration : le builder doit gérer les composants facultatifs avec élégance.Après la construction, appelez
showSpecs()sur l'ordinateur obtenu pour afficher sa configuration.
La méthode showSpecs() doit produire le format suivant (en affichant uniquement les composants qui ont été définis) :
CPU: [value]
RAM: [value]
Storage: [value]
GPU: [value]
Wifi: EnabledPar exemple, avec les entrées Intel i7-12700K, 32GB DDR5, 1TB NVMe SSD et yes :
CPU: Intel i7-12700K
RAM: 32GB DDR5
Storage: 1TB NVMe SSD
Wifi: EnabledAvec les entrées AMD Ryzen 5 5600X, 16GB DDR4, 512GB SSD et no :
CPU: AMD Ryzen 5 5600X
RAM: 16GB DDR4
Storage: 512GB SSDRemarquez comment le patron Builder rend le processus de construction lisible et flexible. Vous pouvez facilement ajouter ou ignorer des composants, et le chaînage des méthodes produit un code clair qui se documente lui-même. La ligne du GPU n'apparaît pas, car nous ne l'avons jamais défini, ce qui montre comment les builders gèrent naturellement les composants facultatifs.
Essayez vous-même
#include <iostream>
#include <string>
#include "ComputerBuilder.h"
using namespace std;
int main() {
// Lire les entrées
string cpu, ram, storage, wifiChoice;
getline(cin, cpu);
getline(cin, ram);
getline(cin, storage);
getline(cin, wifiChoice);
// TODO: Créer une instance de ComputerBuilder
// TODO: Utiliser le chaînage de méthodes pour définir CPU, RAM et storage
// TODO: Si wifiChoice est "yes", appeler aussi addWifi()
// TODO: Appeler build() pour obtenir l'objet Computer
// TODO: Appeler showSpecs() sur l'ordinateur construit pour afficher la configuration
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