Pattern Builder
Fa parte della sezione Programmazione orientata agli oggetti del percorso C++ di Coddy. Lezione 93 di 104.
Il pattern Builder separa la costruzione di un oggetto complesso dalla sua rappresentazione, permettendoti di creare configurazioni diverse passo dopo passo. È particolarmente utile quando un oggetto ha molti parametri opzionali o richiede una sequenza di costruzione specifica.
Invece di un costruttore con molti parametri (che diventa confuso), Builder fornisce metodi chiari e denominati per ogni opzione di configurazione:
#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();
}Ogni metodo setter restituisce un riferimento al builder (return *this), consentendo di concatenare i metodi per ottenere un’interfaccia fluida. Il metodo build() finalizza e restituisce l’oggetto costruito.
Usa Builder quando costruisci oggetti con molti componenti facoltativi, quando vuoi un codice di costruzione leggibile o quando lo stesso processo di costruzione dovrebbe creare rappresentazioni diverse.
Sfida
FacileCostruiamo un sistema Computer Builder che consenta agli utenti di configurare PC personalizzati passo dopo passo. È uno scenario perfetto per il pattern Builder: i computer hanno molti componenti opzionali e vogliamo un modo chiaro e leggibile per assemblare configurazioni diverse.
Organizzerai il codice in tre file:
Computer.h: definisci la classe prodotto che rappresenta un computer completamente configurato.La classe
Computerdovrebbe memorizzare questi componenti come membri privati:cpu(stringa),ram(stringa),storage(stringa),gpu(stringa) ehasWifi(booleano). InizializzahasWifiafalsee, per impostazione predefinita, assegna stringhe vuote alle stringhe.Aggiungi un metodo pubblico chiamato
showSpecs()che visualizzi la configurazione del computer. Per ogni componente che è stato impostato (stringa non vuota), stampalo su una riga separata. La funzionalità Wi-Fi dovrebbe essere stampata solo se è abilitata.ComputerBuilder.h: crea la classe builder che costruisce i computer con un'interfaccia fluida.La classe
ComputerBuilderdovrebbe avere un membro privatoComputerche costruisce progressivamente. Implementa questi metodi, ciascuno dei quali restituisce un riferimento al builder per consentire il concatenamento dei metodi:setCPU(const std::string& cpu)setRAM(const std::string& ram)setStorage(const std::string& storage)setGPU(const std::string& gpu)addWifi(): abilita la funzionalità Wi-Fi
Implementa anche un metodo
build()che restituisca l'oggettoComputercompletato e ripristini il builder per un eventuale riutilizzo.main.cpp: metti tutto insieme per costruire un computer personalizzato.Leggi quattro input:
- Modello della CPU (stringa)
- Specifiche della RAM (stringa)
- Specifiche dello spazio di archiviazione (stringa)
- Se includere il Wi-Fi:
yesono
Usa
ComputerBuilderper costruire un computer con la CPU, la RAM e lo spazio di archiviazione forniti. Se l'input per il Wi-Fi èyes, chiama ancheaddWifi(). Nota che in questa configurazione non è specificata alcuna GPU: il builder dovrebbe gestire con flessibilità i componenti opzionali.Dopo averlo costruito, chiama
showSpecs()sul computer risultante per visualizzarne la configurazione.
Il metodo showSpecs() dovrebbe produrre un output in questo formato (mostrando solo i componenti impostati):
CPU: [value]
RAM: [value]
Storage: [value]
GPU: [value]
Wifi: EnabledAd esempio, con gli input Intel i7-12700K, 32GB DDR5, 1TB NVMe SSD e yes:
CPU: Intel i7-12700K
RAM: 32GB DDR5
Storage: 1TB NVMe SSD
Wifi: EnabledCon gli input AMD Ryzen 5 5600X, 16GB DDR4, 512GB SSD e no:
CPU: AMD Ryzen 5 5600X
RAM: 16GB DDR4
Storage: 512GB SSDNota come il pattern Builder renda il processo di costruzione leggibile e flessibile. Puoi aggiungere o saltare facilmente dei componenti e il concatenamento dei metodi produce codice chiaro e autoesplicativo. La riga della GPU non compare perché non l'abbiamo mai impostata: questo dimostra come i builder gestiscano in modo naturale i componenti opzionali.
Provalo tu
#include <iostream>
#include <string>
#include "ComputerBuilder.h"
using namespace std;
int main() {
// Leggi i valori in input
string cpu, ram, storage, wifiChoice;
getline(cin, cpu);
getline(cin, ram);
getline(cin, storage);
getline(cin, wifiChoice);
// TODO: Crea un'istanza di ComputerBuilder
// TODO: Usa il concatenamento dei metodi per impostare CPU, RAM e la memoria di archiviazione
// TODO: Se wifiChoice è "yes", chiama anche addWifi()
// TODO: Chiama build() per ottenere l'oggetto Computer
// TODO: Chiama showSpecs() sul computer creato per visualizzare la configurazione
return 0;
}
Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.
Tutte le lezioni di Programmazione orientata agli oggetti
1Fondamenti della programmazione orientata agli oggetti
File esterniBuild e compilazione in C++File header e file sorgenteNamespace e ambitoIntroduzione alla programmazione orientata agli oggetti in C++Classi e oggetti a confrontoIl puntatore 'this'Metodi (funzioni membro)Attributi (membri dati)Fondamenti di costruttori e distruttoriRiepilogo - Calcolatrice semplice4Proprietà delle classi
Membri di istanza e staticiGetter e setterFunzioni membro constParola chiave mutableMetodi e variabili staticiFunzioni e classi friendRiepilogo - Gestore di conti bancari7Ereditarietà
Ereditarietà di baseLivelli di accesso nell’ereditarietàOrdine di chiamata di costruttori e distruttoriRidefinizione dei metodiFunzioni virtuali e VTableEreditarietà multiplaEreditarietà virtualeRiepilogo - Gerarchia dei dipendenti10Panoramica della STL
Panoramica e filosofia della STLContenitori STLIteratoriAlgoritmi STLFuntori ed espressioni lambdaRiepilogo - Frequenza delle parole13Design Pattern Parte 1
Introduzione ai Design PatternPattern SingletonFactory e Abstract FactoryPattern BuilderPattern ObserverPattern Strategy2Gestione della memoria
Memoria Stack vs HeapPuntatori e riferimentiMemoria dinamica (new/delete)Puntatori intelligenti in C++RAII in C++Riepilogo - Gestore di array dinamico5Incapsulamento
Specificatori di accesso in C++Specificatori di accesso in dettaglioOccultamento delle informazioniStruct vs classClassi annidate e interneRiepilogo - Sistema di registrazione degli studenti8Polimorfismo
Polimorfismo a compile time e a runtimeOverload delle funzioniFunzioni virtuali: ripassoFunzioni virtuali pureClassi astratteProgettazione delle interfacce in C++Dynamic casting e RTTIRipasso: calcolatrice di forme11Concetti avanzati di OOP
Composizione vs ereditarietàMixin tramite CRTPIdiom PimplType ErasureEnum class e tipizzazione forteGestione delle eccezioni in OOPGerarchie personalizzate di eccezioni14Pattern di progettazione - Parte 2
Pattern CommandPattern AdapterPattern DecoratorPattern Template MethodPattern StatePattern CompositeRAII come pattern3Costruttori e distruttori
Costruttore predefinitoCostruttore con parametriCostruttore di copiaCostruttore di spostamentoListe di inizializzazione dei costruttoriCostruttori delegantiApprofondimento sui distruttoriRegola del Tre / Cinque / ZeroRipasso - classe String6Sovraccarico degli operatori
Introduzione al sovraccarico degli operatoriSovraccarico degli operatori aritmeticiSovraccarico degli operatori di confrontoOperatori di flussoSovraccarico dell'operatore di assegnazioneSovraccarico degli operatori [] e ()Operatori di conversione di tipoRipasso - Classe Matrix9Template
Template di funzioneTemplate di classeSpecializzazione dei templateTemplate variadiciBasi di SFINAE e dei trait di tipoRiepilogo - Contenitore genericoEsercitati da solo: Compilatore C++ online