Menu
Coddy logo textTech

Funções Factory

Parte da seção Object Oriented Programming do Journey de Lua da Coddy — lição 62 de 70.

Ao longo deste curso, você criou objetos chamando construtores diretamente — Circle:new(), Rectangle:new() e assim por diante. Mas e se você quiser criar diferentes tipos de objetos com base em alguma condição, sem que o código de chamada precise saber qual classe específica usar?

É aqui que o padrão Factory entra em cena. Uma factory é simplesmente uma função que cria e retorna objetos. O principal benefício é que quem chama não precisa conhecer os detalhes da criação do objeto — ele apenas solicita à factory o que precisa.

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

-- O chamador não precisa saber sobre as classes Circle ou Square
local myShape = createShape("circle")
print(myShape:area())

A função factory recebe um argumento de string e decide qual classe instanciar. Isso centraliza a lógica de criação de objetos em um só lugar. Se você adicionar posteriormente um novo tipo de forma, você modifica apenas a factory — não cada parte do código que cria formas.

Factories são especialmente úteis quando a criação de objetos envolve uma configuração complexa, quando você deseja ocultar detalhes de implementação ou quando o tipo exato de objeto depende de condições de tempo de execução, como entrada do usuário ou arquivos de configuração.

challenge icon

Desafio

Fácil

Vamos construir uma Pet Factory! Em vez de criar animais de estimação diretamente chamando o construtor de cada classe, você criará uma função de fábrica que produz o tipo certo de animal com base em um simples argumento de string.

Você organizará seu código em quatro arquivos:

  • Dog.lua: Crie uma classe Dog com um construtor :new(name) que armazena o nome do animal. Adicione um método :speak() que retorna a string "{name} says: Woof!" (onde {name} é o nome do cachorro).
  • Cat.lua: Crie uma classe Cat com a mesma estrutura — um construtor :new(name) e um método :speak() que retorna "{name} says: Meow!".
  • PetFactory.lua: É aqui que o padrão Factory brilha! Crie uma função createPet(petType, name) que recebe dois argumentos: uma string indicando o tipo do animal ("dog" ou "cat") e o nome do animal. A função deve retornar o objeto de animal apropriado. Se o tipo for "dog", retorne um novo Dog; se for "cat", retorne um novo Cat.
  • main.lua: Importe seu módulo PetFactory. Leia duas entradas: o tipo do animal e o nome do animal. Use sua função de fábrica para criar o animal, então chame seu método :speak() e imprima o resultado.

A beleza do padrão Factory é que seu código principal não precisa importar Dog ou Cat diretamente — ele conhece apenas a fábrica. A fábrica cuida de todos os detalhes de qual classe instanciar.

Você receberá duas entradas:

  1. Tipo do animal (seja "dog" ou "cat")
  2. Nome do animal (uma string)

Por exemplo, se as entradas forem dog e Buddy, a saída deve ser:

Buddy says: Woof!

Se as entradas forem cat e Whiskers, a saída deve ser:

Whiskers says: Meow!

Folha de consulta

O padrão Factory (ou Fábrica) é um padrão de projeto onde uma função cria e retorna objetos com base em parâmetros fornecidos. O chamador não precisa saber qual classe específica está sendo instanciada — a fábrica cuida dessa decisão.

Uma função fábrica centraliza a lógica de criação 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())

Benefícios do padrão Factory:

  • Esconde detalhes de implementação do chamador
  • Centraliza a criação de objetos em um só lugar
  • Torna fácil adicionar novos tipos — apenas a fábrica precisa de modificação
  • Útil quando o tipo de objeto depende de condições de tempo de execução (entrada do usuário, configuração, etc.)
  • Útil quando a criação do objeto envolve uma configuração complexa

Experimente você mesmo

-- main.lua
-- Use o PetFactory para criar pets

local PetFactory = require('PetFactory')

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

-- TODO: Use PetFactory.createPet para criar o pet
-- TODO: Chame o método :speak() do pet e imprima o resultado
quiz iconTeste seus conhecimentos

Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.

Todas as lições de Object Oriented Programming