Menu
CoddyTech

Patrón Builder

Parte de la sección Programación Orientada a Objetos del Journey de C++ de Coddy. Lección 93 de 104.

El patrón Builder separa la construcción de un objeto complejo de su representación, lo que te permite crear distintas configuraciones paso a paso. Esto es especialmente útil cuando un objeto tiene muchos parámetros opcionales o requiere una secuencia de construcción específica.

En lugar de un constructor con muchos parámetros (que resulta confuso), Builder proporciona métodos claros y con nombre para cada opción de configuración:

#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();
}

Cada método de configuración devuelve una referencia al constructor (return *this), lo que permite encadenar métodos para crear una interfaz fluida. El método build() finaliza y devuelve el objeto construido.

Usa Builder cuando construyas objetos con muchos componentes opcionales, cuando quieras un código de construcción legible o cuando el mismo proceso de construcción deba crear distintas representaciones.

challenge icon

Desafío

Fácil

Vamos a crear un sistema Computer Builder que permita a los usuarios configurar PC personalizadas paso a paso. Este es un escenario perfecto para el patrón Builder: las computadoras tienen muchos componentes opcionales y queremos una forma clara y legible de ensamblar distintas configuraciones.

Organizarás el código en tres archivos:

  • Computer.h: define la clase del producto que representa una computadora completamente configurada.

    Tu clase Computer debe almacenar estos componentes como miembros privados: cpu (cadena), ram (cadena), storage (cadena), gpu (cadena) y hasWifi (booleano). Inicializa hasWifi en false y, de forma predeterminada, las cadenas en vacío.

    Añade un método público llamado showSpecs() que muestre la configuración de la computadora. Para cada componente que se haya establecido (cadena no vacía), imprímelo en su propia línea. La capacidad wifi solo debe mostrarse si está habilitada.

  • ComputerBuilder.h: crea la clase constructora que construye computadoras con una interfaz fluida.

    Tu clase ComputerBuilder debe tener un miembro privado Computer que irá construyendo. Implementa estos métodos, cada uno de los cuales devuelve una referencia a la clase constructora para permitir encadenar métodos:

    • setCPU(const std::string& cpu)
    • setRAM(const std::string& ram)
    • setStorage(const std::string& storage)
    • setGPU(const std::string& gpu)
    • addWifi(): habilita la capacidad wifi

    Implementa también un método build() que devuelva el objeto Computer terminado y restablezca la clase constructora para que pueda reutilizarse.

  • main.cpp: integra todo para construir una computadora personalizada.

    Lee cuatro entradas:

    1. Modelo de CPU (cadena)
    2. Especificación de RAM (cadena)
    3. Especificación de almacenamiento (cadena)
    4. Si se debe incluir wifi: yes o no

    Usa ComputerBuilder para construir una computadora con la CPU, la RAM y el almacenamiento proporcionados. Si la entrada de wifi es yes, llama también a addWifi(). Ten en cuenta que en esta configuración no se especifica ninguna GPU: la clase constructora debe gestionar los componentes opcionales sin problemas.

    Después de construirla, llama a showSpecs() en la computadora resultante para mostrar su configuración.

El método showSpecs() debe mostrar la salida con este formato (mostrando solo los componentes establecidos):

CPU: [value]
RAM: [value]
Storage: [value]
GPU: [value]
Wifi: Enabled

Por ejemplo, con las entradas Intel i7-12700K, 32GB DDR5, 1TB NVMe SSD y yes:

CPU: Intel i7-12700K
RAM: 32GB DDR5
Storage: 1TB NVMe SSD
Wifi: Enabled

Con las entradas AMD Ryzen 5 5600X, 16GB DDR4, 512GB SSD y no:

CPU: AMD Ryzen 5 5600X
RAM: 16GB DDR4
Storage: 512GB SSD

Observa cómo el patrón Builder hace que el proceso de construcción sea legible y flexible. Puedes añadir u omitir componentes fácilmente, y el encadenamiento de métodos crea un código claro que se explica por sí mismo. La línea de la GPU no aparece porque nunca la establecemos, lo que demuestra cómo las clases constructoras gestionan los componentes opcionales de forma natural.

Pruébalo tú mismo

#include <iostream>
#include <string>
#include "ComputerBuilder.h"

using namespace std;

int main() {
    // Lee las entradas
    string cpu, ram, storage, wifiChoice;
    getline(cin, cpu);
    getline(cin, ram);
    getline(cin, storage);
    getline(cin, wifiChoice);

    // TODO: Crea una instancia de ComputerBuilder
    
    // TODO: Usa el encadenamiento de métodos para configurar CPU, RAM y el almacenamiento
    
    // TODO: Si wifiChoice es "yes", llama también a addWifi()
    
    // TODO: Llama a build() para obtener el objeto Computer
    
    // TODO: Llama a showSpecs() en el equipo construido para mostrar la configuración

    return 0;
}
quiz iconPonte a prueba

Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.

Todas las lecciones de Programación Orientada a Objetos

Practica por tu cuenta: Compilador de C++ online