Regístrate para acceder a más de 15 cursos gratuitos de programación con un simulador

Fábrica (Patrón de diseño) Python: Polimorfismo

Cuando estamos desarrollando software, algunas veces necesitamos crear objetos de distintas clases que comparten una funcionalidad común, pero cada uno se comporta de manera diferente. Además, puede que la lógica para crear esos objetos sea compleja o simplemente queramos que otros usen nuestros objetos sin tener que preocuparse por cómo se crean.

Aquí es donde entra el patrón de diseño llamado Fábrica, una forma elegante de crear objetos que te ayuda a mantener tu código organizado y fácil de extender.

¿Qué es el patrón Fábrica?

Es una técnica en la que usamos una función o clase especial para encargarse de crear objetos. En vez de crear el objeto directamente con su clase, dejamos que la fábrica decida qué clase usar y nos devuelva el objeto listo para usar.

Esto es útil especialmente cuando:

  • Hay varios tipos de objetos que pueden ser creados.
  • El proceso de creación de los objetos puede cambiar o es complejo.
  • Queremos ocultarle detalles técnicos al resto del programa.

Veamos cómo funciona esto con un ejemplo práctico.

Ejemplo: Animales en un zoológico

🦁🐯🐻 Imaginemos que estamos creando un programa para un zoológico virtual. Tenemos diferentes tipos de animales (León, Tigre, Oso) y todos ellos pueden hacer un sonido.

Paso 1: Creamos una clase base y las clases hijas

Primero definimos una clase base llamada Animal, y luego otras clases específicas que heredan de esta. Cada clase implementa su propia versión del método make_sound (hacer sonido).

# Clase base
class Animal():
    def make_sound(self):
        pass  # Método que cada subclase debe implementar

# Subclases
class Lion(Animal):
    def make_sound(self):
        return "Roar"  # Sonido del león

class Tiger(Animal):
    def make_sound(self):
        return "Growl"  # Sonido del tigre

class Bear(Animal):
    def make_sound(self):
        return "Grr"  # Sonido del oso

Estas clases heredan de Animal, lo que significa que todas comparten un comportamiento común, pero cada una lo ejecuta a su manera.

Paso 2: Creamos la fábrica de animales

Ahora definimos una clase llamada AnimalFactory, que tiene un método llamado create_animal. Esta es nuestra fábrica. Su tarea es recibir el tipo de animal como texto (por ejemplo, "Lion") y devolver una instancia del animal correspondiente.

Vamos a usar un diccionario para mapear los nombres a las clases. Esto hace que el código sea más limpio y fácil de expandir.

class AnimalFactory:
    # Diccionario que asocia tipos de animales con sus clases
    animal_classes = {
        "Lion": Lion,
        "Tiger": Tiger,
        "Bear": Bear
    }

    @staticmethod
    def create_animal(animal_type):
        # Verificamos si el tipo está en nuestro diccionario
        if animal_type in AnimalFactory.animal_classes:
            return AnimalFactory.animal_classes[animal_type]()  # Creamos el objeto
        else:
            raise ValueError("Tipo de animal no válido")

Nota: Usamos @staticmethod porque no necesitamos crear una instancia de AnimalFactory para usar este método.

Paso 3: Usamos la fábrica para crear animales

Ahora vemos cómo usar esta fábrica:

# Creamos animales usando la fábrica
leon = AnimalFactory.create_animal("Lion")
print(leon.make_sound())  # Imprime: Roar

tigre = AnimalFactory.create_animal("Tiger")
print(tigre.make_sound())  # Imprime: Growl

oso = AnimalFactory.create_animal("Bear")
print(oso.make_sound())  # Imprime: Grr

Lo interesante aquí es que usamos el mismo método create_animal() para crear distintos tipos de animales. Ya no necesitamos preocuparnos por qué clase crear directamente. Solo le decimos a la fábrica qué tipo queremos y ella se encarga del resto.

🐺 Además, si en el futuro queremos agregar un nuevo animal (por ejemplo, Wolf), solo necesitamos:

  1. Crear una nueva clase Wolf que herede de Animal.
  2. Agregar "Wolf": Wolf al diccionario animal_classes.

No necesitamos tocar el resto del código.

¿Por qué usar una fábrica?

Este patrón es muy útil cuando:

  • Tenemos que crear objetos de diferentes tipos, pero que tienen una funcionalidad parecida.
  • Queremos separar la lógica de creación de los objetos del resto del programa.
  • Anticipamos que en el futuro necesitaremos agregar más tipos de objetos.

Sin embargo, no siempre es necesario. Si solo tienes un tipo de objeto, o la lógica de creación es muy simple, usar una fábrica puede hacer el código innecesariamente complejo.

Tabla de comparación

Enfoque Directo Patrón Fábrica
Crear instancias directamente Usar un método específico
Necesario conocer la clase Solo se necesita el tipo (string)
Dificultad para cambiar lógica Fábrica centraliza la lógica
Código repetido en varios sitios Código más limpio y sostenible



Resumen

  • El patrón Fábrica nos permite crear objetos sin saber exactamente cómo se crean internamente.
  • Utiliza una función o clase especializada para encargarse de la construcción del objeto.
  • Es ideal cuando se trabaja con varios tipos de objetos derivados de una clase base.
  • Puede ser excesivo si solo se necesita crear un tipo de objeto o si la lógica es sencilla.

Para acceder completo a curso necesitas un plan básico

El plan básico te dará acceso completo a todos los cursos, ejercicios y lecciones de Códica, proyectos y acceso de por vida a la teoría de las lecciones completadas. La suscripción se puede cancelar en cualquier momento.

Obtener acceso
130
cursos
1000
ejercicios
2000+
horas de teoría
3200
test

Obtén acceso

Cursos de programación para principiantes y desarrolladores experimentados. Comienza tu aprendizaje de forma gratuita

  • 130 cursos, 2000+ horas de teoría
  • 1000 ejercicios prácticos en el navegador
  • 360 000 estudiantes
Al enviar el formulario, aceptas el «Política de privacidad» y los términos de la «Oferta», y también aceptas los «Términos y condiciones de uso»

Nuestros graduados trabajan en empresas como:

Bookmate
Health Samurai
Dualboot
ABBYY