- ¿Qué es el patrón Fábrica?
- Ejemplo: Animales en un zoológico
- ¿Por qué usar una fábrica?
- Tabla de comparación
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?
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:
- Crear una nueva clase
Wolfque herede deAnimal. - Agregar
"Wolf": Wolfal diccionarioanimal_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.