Menu
Coddy logo textTech

Funções Factory

Parte da seção Programação Orientada a Objetos 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 entra o padrão Factory. Uma factory é simplesmente uma função que cria e retorna objetos. O principal benefício é que quem faz a chamada não precisa conhecer os detalhes da criação do objeto. Basta pedir à factory aquilo de 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 de fábrica recebe um argumento do tipo string e decide qual classe instanciar. Isso centraliza a lógica de criação de objetos em um único lugar. Se você adicionar um novo tipo de forma posteriormente, modificará apenas a fábrica, e não cada trecho de código que cria formas.

As fábricas são especialmente úteis quando a criação de object envolve uma configuração complexa, quando você quer ocultar detalhes de implementação ou quando o tipo exato de object depende de condições de execução, como entradas do usuário ou arquivos de configuração.

challenge icon

Desafio

Fácil

Vamos criar uma Pet Factory! Em vez de criar pets diretamente chamando o construtor de cada classe, você criará uma função de fábrica que produz o tipo certo de pet com base em um argumento simples do tipo 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 pet. Adicione um método :speak() que retorna a string "{name} says: Woof!" (em que {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 se destaca! Crie uma função createPet(petType, name) que receba dois argumentos: uma string indicando o tipo de pet ("dog" ou "cat") e o nome do pet. A função deve retornar o objeto de pet apropriado. Se o tipo for "dog", retorne um novo Dog; se for "cat", retorne um novo Cat.
  • main.lua: importe o módulo PetFactory. Leia duas entradas: o tipo de pet e o nome do pet. Use sua função de fábrica para criar o pet e, em seguida, 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 de pet (pode ser "dog" ou "cat")
  2. Nome do pet (uma string)

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

Buddy says: Woof!

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

Whiskers says: Meow!

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 Programação Orientada a Objetos

Pratique por conta própria: Compilador de Lua online