Menu
Coddy logo textTech

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 resulta 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 se vuelve confuso), Builder proporciona métodos claros y con nombres 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 setter devuelve una referencia al builder (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 diferentes representaciones.

challenge icon

Desafío

Fácil

Construyamos un sistema de Computer Builder que permita a los usuarios configurar PCs personalizados paso a paso. Este es un escenario perfecto para el patrón Builder: los ordenadores tienen muchos componentes opcionales y queremos una forma limpia y legible de ensamblar distintas configuraciones.

Organizarás tu código en tres archivos:

  • Computer.h: Define la clase de producto que representa un ordenador completamente configurado.

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

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

  • ComputerBuilder.h: Crea la clase constructora que construye ordenadores mediante una interfaz fluida.

    Tu clase ComputerBuilder debe tener un miembro privado Computer que irá construyendo. Implementa estos métodos, cada uno devolviendo una referencia al constructor para permitir el encadenamiento de 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 completado y restablezca el constructor para poder reutilizarlo.

  • main.cpp: Une todos los elementos para construir un ordenador personalizado.

    Lee cuatro entradas:

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

    Usa ComputerBuilder para construir un ordenador 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 no se especifica ninguna GPU en esta configuración: el constructor debe gestionar los componentes opcionales correctamente.

    Después de construirlo, llama a showSpecs() en el ordenador resultante para mostrar su configuración.

El método showSpecs() debe mostrar el siguiente formato (mostrando únicamente los componentes que se hayan establecido):

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 y autodocumentado. La línea de la GPU no aparece porque nunca la establecimos, lo que demuestra cómo los constructores gestionan los componentes opcionales de forma natural.

Pruébalo tú mismo

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

using namespace std;

int main() {
    // Leer 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 establecer CPU, RAM y storage
    
    // TODO: Si wifiChoice es "yes", también llama a addWifi()
    
    // TODO: Llama a build() para obtener el objeto Computer
    
    // TODO: Llama a showSpecs() en la computadora construida 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