🚨 ¡Nueva review! ✨ Mi ratón favorito para programar: el Logitech MX Master 3S . ¡Échale un ojo! 👀

Patrón Abstract Factory: La Fábrica de Familias de Objetos (Explicación para Dummies)

¿Qué es y cuándo usar el patrón Abstract Factory?

Escrito por domin el 27/09/2025

Patrón de Diseño Abstract Factory: El Kit de Creación de Familias 🚗

Imagina que estás programando el sistema de pedidos de un gran grupo automovilístico. Necesitas crear coches, pero tienes dos familias de vehículos muy diferentes: la gama “SEAT” (práctica y familiar) y la gama “CUPRA” (deportiva y de altas prestaciones).

Abstract Factory Method

El Patrón de Diseño Abstract Factory es como tener una “Fábrica de Fábricas” o un “Maestro Constructor de Temas”. Su función es permitirte crear familias de objetos relacionados o dependientes (como un motor, un chasis y unos asientos), garantizando que todos pertenezcan a la misma línea de diseño (o la familia SEAT o la familia CUPRA).


¿En qué Consiste?

Este patrón te permite trabajar con interfaces (contratos) sin conocer el nombre de las clases específicas.

Los Tres Roles Principales:

  1. Abstract Factory (La Receta General): Es una interfaz o clase abstracta, el contrato principal. Declara el conjunto de métodos que deben seguir todas las fábricas. Es la promesa de que “esta fábrica sabrá cómo hacer un Motor y un Asiento”. Ejemplo: La interfaz CocheFactory.
  2. Concrete Factory (Las Fábricas Específicas): Son las implementaciones concretas de la Abstract Factory. Cada una crea productos de una familia específica.
    • SeatFactory (Crea productos de la familia SEAT).
    • CupraFactory (Crea productos de la familia CUPRA).
  3. Abstract Product y Concrete Product (Los Componentes y sus Versiones): Son los objetos que se crean. El Abstract Product es la interfaz genérica del componente (Motor, Asiento), y el Concrete Product es la versión específica.
    • MotorSeat y AsientoSeat (Pertenecen a la familia SEAT).
    • MotorCupra y AsientoCupra (Pertenecen a la familia CUPRA).

La Gran Ventaja: Intercambiabilidad Garantizada

Lo guapo del Abstract Factory es que si en tu código necesitas construir un coche completo, solo tienes que decidir al inicio qué Concrete Factory vas a usar (SeatFactory o CupraFactory). Todo lo que pidas después a esa fábrica estará garantizadamente en línea con esa familia, sin tener que cambiar el resto de tu código.


Ejemplo de la Vida Real: SEAT vs. CUPRA 🏎️

Imagina que quieres montar un coche:

Componente del PatrónEjemplo en Automoción
Abstract FactoryMarcaCocheFactory (Métodos: crearMotor(), crearAsiento())
Concrete FactorySeatFactory o CupraFactory
Abstract ProductMotor y Asiento (Interfaces genéricas)
Concrete ProductMotorSeat, AsientoCupra, MotorCupra, etc.

Flujo de Trabajo

  1. Decisión Inicial: El cliente pide un coche CUPRA.
  2. Creación de la Fábrica: Tu código crea la Concrete Factory: new CupraFactory().
  3. Uso (Cliente): Para construir el coche, tu código (el cliente) solo usa los métodos de la interfaz MarcaCocheFactory:
    • $motor = $fabrica->crearMotor();
    • $asiento = $fabrica->crearAsiento();
  4. Resultado: El código cliente recibe un MotorCupra y un AsientoCupra. Si mañana quiere un SEAT, solo cambia la línea de la creación de la fábrica (new SeatFactory()), y recibirá automáticamente el MotorSeat y el AsientoSeat, sin tocar el código de montaje. ¡Magic! 🧙‍♀️

Ejemplo de Código en PHP

Este es un ejemplo simplificado de cómo se vería la estructura en PHP, siguiendo el ejemplo de los coches.

1. Las Interfaces (Abstract Factory y Abstract Products)

<?php

// Abstract Products: Los componentes que queremos
interface Motor {
    public function obtenerTipoMotor(): string;
}

interface Asiento {
    public function obtenerMaterial(): string;
}

// Abstract Factory: El contrato para todas las fábricas
interface MarcaCocheFactory {
    public function crearMotor(): Motor;
    public function crearAsiento(): Asiento;
}
?>

2. Los Productos Concretos (Las Familias)

<?php
// Productos Concretos de la Familia SEAT
class MotorSeat implements Motor {
    public function obtenerTipoMotor(): string {
        return "Motor SEAT 1.0 TSI (Eficiente y económico)";
    }
}

class AsientoSeat implements Asiento {
    public function obtenerMaterial(): string {
        return "Asiento SEAT (Tela con diseño práctico)";
    }
}

// Productos Concretos de la Familia CUPRA
class MotorCupra implements Motor {
    public function obtenerTipoMotor(): string {
        return "Motor CUPRA 2.0 TSi (Alto rendimiento y deportivo)";
    }
}

class AsientoCupra implements Asiento {
    public function obtenerMaterial(): string {
        return "Asiento CUPRA (Piel perforada y deportivo)";
    }
}

3. Las Fábricas Concretas (Concrete Factories)

<?php
// Concrete Factory para la familia SEAT
class SeatFactory implements MarcaCocheFactory {
    public function crearMotor(): Motor {
        return new MotorSeat();
    }
    public function crearAsiento(): Asiento {
        return new AsientoSeat();
    }
}

// Concrete Factory para la familia CUPRA
class CupraFactory implements MarcaCocheFactory {
    public function crearMotor(): Motor {
        return new MotorCupra();
    }
    public function crearAsiento(): Asiento {
        return new AsientoCupra();
    }
}

4. El Código Cliente (El Montador)

El código cliente solo interactúa con las interfaces y no conoce los nombres de las clases concretas (MotorSeat, AsientoCupra, etc.).

<?php
// El código cliente que usa la fábrica para montar un coche
function montarCoche(MarcaCocheFactory $fabrica) {
    $motor = $fabrica->crearMotor();
    $asiento = $fabrica->crearAsiento();

    echo "--- Montando Coche --- \n";
    echo "Motor: " . $motor->obtenerTipoMotor() . "\n";
    echo "Asiento: " . $asiento->obtenerMaterial() . "\n";
    echo "------------------------ \n";
}

// Caso 1: Creamos un coche SEAT
$fabricaSeat = new SeatFactory();
montarCoche($fabricaSeat);

// Caso 2: Cambiamos a un coche CUPRA, ¡solo cambiando la fábrica!
$fabricaCupra = new CupraFactory();
montarCoche($fabricaCupra);

/*
Salida esperada:
--- Montando Coche ---
Motor: Motor SEAT 1.0 TSI (Eficiente y económico)
Asiento: Asiento SEAT (Tela con diseño práctico)
------------------------
--- Montando Coche ---
Motor: Motor CUPRA 2.0 TSi (Alto rendimiento y deportivo)
Asiento: Asiento CUPRA (Piel perforada y deportivo)
------------------------
*/

Ejercicio Práctico 🧠

Para que termines de entender la potencia del Abstract Factory, te propongo este ejercicio:

Tu tarea: Añadir una nueva familia al sistema de coches: la marca SKODA.

En el código cliente, instancia la SkodaFactory y llama a la función montarCoche() con ella.

Si consigues que tu código imprima la línea de SKODA sin modificar la función montarCoche(), ¡habrás entendido perfectamente el patrón Abstract Factory!

EA, nos vemos en los bares! 🍺 saluditos