Menu
Coddy logo textTech

Funciones Factory

Parte de la sección Object Oriented Programming del Journey de Lua de Coddy — lección 62 de 70.

A lo largo de este curso, has creado objetos llamando a los constructores directamente—Circle:new(), Rectangle:new(), y así sucesivamente. Pero, ¿qué pasa si quieres crear diferentes tipos de objetos basándote en alguna condición, sin que el código que realiza la llamada necesite saber qué clase específica utilizar?

Aquí es donde entra en juego el patrón Factory. Una fábrica es simplemente una función que crea y devuelve objetos. El beneficio clave es que quien realiza la llamada no necesita conocer los detalles de la creación del objeto; simplemente le pide a la fábrica lo que necesita.

local function createShape(shapeType)
    if shapeType == "circle" then
        return Circle:new(10)
    elseif shapeType == "square" then
        return Square:new(5)
    end
end

-- El llamador no necesita conocer las clases Circle o Square
local myShape = createShape("circle")
print(myShape:area())

La función de fábrica toma un argumento de cadena y decide qué clase instanciar. Esto centraliza la lógica de creación de objetos en un solo lugar. Si más adelante agregas un nuevo tipo de forma, solo modificas la fábrica, no cada fragmento de código que crea formas.

Las fábricas son especialmente útiles cuando la creación de objetos implica una configuración compleja, cuando se desea ocultar los detalles de implementación o cuando el tipo exacto de objeto depende de condiciones en tiempo de ejecución, como la entrada del usuario o los archivos de configuración.

challenge icon

Desafío

Fácil

¡Vamos a construir una Pet Factory! En lugar de crear mascotas directamente llamando al constructor de cada clase, crearás una función de fábrica que produzca el tipo correcto de mascota basándose en un simple argumento de cadena.

Organizarás tu código en cuatro archivos:

  • Dog.lua: Crea una clase Dog con un constructor :new(name) que almacene el nombre de la mascota. Añade un método :speak() que devuelva la cadena "{name} says: Woof!" (donde {name} es el nombre del perro).
  • Cat.lua: Crea una clase Cat con la misma estructura: un constructor :new(name) y un método :speak() que devuelva "{name} says: Meow!".
  • PetFactory.lua: ¡Aquí es donde brilla el patrón Factory! Crea una función createPet(petType, name) que reciba dos argumentos: una cadena que indique el tipo de mascota ("dog" o "cat") y el nombre de la mascota. La función debe devolver el objeto de mascota apropiado. Si el tipo es "dog", devuelve un nuevo Dog; si es "cat", devuelve un nuevo Cat.
  • main.lua: Requiere tu módulo PetFactory. Lee dos entradas: el tipo de mascota y el nombre de la mascota. Usa tu función de fábrica para crear la mascota, luego llama a su método :speak() e imprime el resultado.

La belleza del patrón Factory es que tu código principal no necesita requerir Dog o Cat directamente; solo conoce la fábrica. La fábrica se encarga de todos los detalles sobre qué clase instanciar.

Recibirás dos entradas:

  1. Tipo de mascota (ya sea "dog" o "cat")
  2. Nombre de la mascota (una cadena)

Por ejemplo, si las entradas son dog y Buddy, la salida debería ser:

Buddy says: Woof!

Si las entradas son cat y Whiskers, la salida debería ser:

Whiskers says: Meow!

Hoja de referencia

El patrón Factory es un patrón de diseño donde una función crea y devuelve objetos basados en parámetros dados. Quien realiza la llamada no necesita saber qué clase específica se está instanciando; la fábrica se encarga de esa decisión.

Una función de fábrica centraliza la lógica de creación de objetos:

local function createShape(shapeType)
    if shapeType == "circle" then
        return Circle:new(10)
    elseif shapeType == "square" then
        return Square:new(5)
    end
end

local myShape = createShape("circle")
print(myShape:area())

Beneficios del patrón Factory:

  • Oculta los detalles de implementación a quien realiza la llamada
  • Centraliza la creación de objetos en un solo lugar
  • Facilita la adición de nuevos tipos: solo la fábrica necesita ser modificada
  • Útil cuando el tipo de objeto depende de condiciones en tiempo de ejecución (entrada del usuario, configuración, etc.)
  • De gran ayuda cuando la creación de objetos implica una configuración compleja

Pruébalo tú mismo

-- main.lua
-- Usa PetFactory para crear mascotas

local PetFactory = require('PetFactory')

-- Leer entradas
local petType = io.read()
local petName = io.read()

-- TODO: Usar PetFactory.createPet para crear la mascota
-- TODO: Llamar al método :speak() de la mascota e imprimir el resultado
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 Object Oriented Programming