Menu
Coddy logo textTech

Patrón Factory

Parte de la sección Programación Orientada a Objetos del Journey de C de Coddy. Lección 55 de 61.

El patrón Factory centraliza la creación de objetos en una sola función. En lugar de dispersar malloc y el código de inicialización por todo tu programa, llamas a una función que decide qué crear y devuelve un objeto listo para usar.

Este patrón es especialmente potente cuando se combina con el polimorfismo. Una fábrica puede devolver distintos tipos concretos mediante un puntero base común, ocultando los detalles de creación al llamador. El llamador simplemente solicita «una forma» y la fábrica decide si construye un círculo, un rectángulo o alguna otra cosa.

Esta es una implementación típica de una fábrica:

typedef enum {
    SHAPE_CIRCLE,
    SHAPE_RECTANGLE
} ShapeType;

Shape* create_shape(ShapeType type) {
    switch (type) {
        case SHAPE_CIRCLE:
            return (Shape*)create_circle(5.0);
        case SHAPE_RECTANGLE:
            return (Shape*)create_rectangle(4.0, 3.0);
        default:
            return NULL;
    }
}

La fábrica recibe un identificador (normalmente un enum) y utiliza una sentencia switch para determinar a qué constructor llamar. Devuelve un Shape* independientemente del tipo real creado. La persona que llama no necesita conocer Circle ni Rectangle. Simplemente trabaja con el tipo base:

Shape* s = create_shape(SHAPE_CIRCLE);
s->draw(s);  // llamada polimórfica
free_shape(s);

Este patrón facilita añadir nuevos tipos: solo tienes que añadir un nuevo valor de enumeración y un nuevo caso en la fábrica. El resto de tu código permanece sin cambios.

challenge icon

Desafío

Fácil

Construyamos una Fábrica de mascotas: un sistema que crea distintos tipos de mascotas mediante una única función de fábrica. En lugar de dispersar la lógica de creación por todo tu código, la centralizarás en un solo lugar que decide qué tipo de mascota crear según un identificador de entrada.

Organizarás tu código en tres archivos:

  • pet.h: Define una enumeración PetType con los valores PET_DOG, PET_CAT y PET_BIRD. Crea una estructura base Pet que contenga un puntero a función para speak (que recibe un const Pet* y no devuelve nada). Declara la función de fábrica create_pet, que recibe un PetType y devuelve un Pet*, además de una función free_pet para la limpieza.
  • pet.c: Define tres estructuras concretas de mascotas, Dog, Cat y Bird, cada una incorporando Pet como su primer miembro. Implementa una función speak para cada tipo:
    • Los perros imprimen: Woof!
    • Los gatos imprimen: Meow!
    • Los pájaros imprimen: Tweet!
    Crea funciones constructoras para cada tipo de mascota que asignen memoria y conecten la función speak correspondiente. Después, implementa la fábrica create_pet: usa una sentencia switch sobre PetType para llamar al constructor correcto y devolver el resultado como un Pet*. Para los tipos no válidos, devuelve NULL. Implementa free_pet para liberar la memoria asignada.
  • main.c: Lee un entero que representa el tipo de mascota (0 para perro, 1 para gato, 2 para pájaro). Usa la fábrica para crear la mascota correspondiente, llama a su función speak polimórficamente mediante el puntero base Pet* y después libera la mascota.

Tu programa recibirá una entrada: un entero que indica qué mascota crear.

Salida de ejemplo cuando la entrada es 0:

Woof!

Salida de ejemplo cuando la entrada es 1:

Meow!

Salida de ejemplo cuando la entrada es 2:

Tweet!

La ventaja del patrón Factory es que main.c no necesita conocer las estructuras Dog, Cat o Bird. Solo trabaja con el tipo base Pet. Añadir un nuevo tipo de mascota más adelante significa agregar un nuevo valor de enumeración y un nuevo caso en la fábrica, sin cambiar ningún código que use mascotas.

Pruébalo tú mismo

#include <stdio.h>
#include "pet.h"

int main(void) {
    int type;
    scanf("%d", &type);
    
    // TODO: Usa la factory para crear el pet apropiado
    // Pista: Haz cast del int a PetType
    
    // TODO: Llama a la función speak polimórficamente a través del puntero Pet*
    
    // TODO: Libera el pet
    
    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