Menu
CoddyTech

Padrão Factory

Parte da seção Programação Orientada a Objetos do Journey de C da Coddy. Lição 55 de 61.

O padrão Factory centraliza a criação de objetos em uma única função. Em vez de espalhar código de malloc e de inicialização pelo programa, você chama uma função que decide o que criar e retorna um objeto pronto para uso.

Esse padrão é especialmente poderoso quando combinado com polimorfismo. Uma fábrica pode retornar tipos concretos diferentes por meio de um ponteiro para uma classe-base comum, ocultando os detalhes da criação de quem faz a chamada. Quem faz a chamada simplesmente pede “uma forma”, e a fábrica decide se deve criar um círculo, um retângulo ou outra coisa.

Veja uma implementação típica de fábrica:

typedef enum {
    SHAPE_CIRCLE,
    SHAPE_RECTANGLE
} ShapeType;

Shape* create_shape(ShapeType type) {
    switch (type) {
        case SHAPE_CIRCLE:
            return (Shape*)create_circle(5.0);
        case SHAPE_RECTANGLE:
            return (Shape*)create_rectangle(4.0, 3.0);
        default:
            return NULL;
    }
}

A fábrica recebe um identificador (geralmente um enum) e usa uma instrução switch para determinar qual construtor chamar. Ela retorna um Shape*, independentemente do tipo real criado. Quem chama não precisa conhecer Circle nem Rectangle. Basta trabalhar com o tipo base:

Shape* s = create_shape(SHAPE_CIRCLE);
s->draw(s);  // chamada polimórfica
free_shape(s);

Esse padrão facilita adicionar novos tipos: basta adicionar um novo valor de enumeração e um novo caso na fábrica. O restante do seu código permanece inalterado.

challenge icon

Desafio

Fácil

Vamos criar uma Fábrica de Pets: um sistema que cria diferentes tipos de pets por meio de uma única função de fábrica. Em vez de espalhar a lógica de criação pelo seu código, você vai centralizá-la em um só lugar, que decide que tipo de pet criar com base em um identificador de entrada.

Você vai organizar seu código em três arquivos:

  • pet.h: Defina um enum PetType com os valores PET_DOG, PET_CAT e PET_BIRD. Crie uma estrutura base Pet que contenha um ponteiro para a função speak (que recebe um const Pet* e não retorna nada). Declare a função de fábrica create_pet, que recebe um PetType e retorna um Pet*, além de uma função free_pet para liberar a memória.
  • pet.c: Defina três estruturas concretas de pets, Dog, Cat e Bird, cada uma incorporando Pet como seu primeiro membro. Implemente uma função speak para cada tipo:
    • Cães imprimem: Woof!
    • Gatos imprimem: Meow!
    • Pássaros imprimem: Tweet!
    Crie funções construtoras para cada tipo de pet que aloquem memória e configurem a função speak apropriada. Em seguida, implemente a fábrica create_pet: use uma instrução switch sobre o PetType para chamar o construtor correto e retornar o resultado como um Pet*. Para tipos inválidos, retorne NULL. Implemente free_pet para liberar a memória alocada.
  • main.c: Leia um número inteiro que representa o tipo de pet (0 para cachorro, 1 para gato, 2 para pássaro). Use sua fábrica para criar o pet apropriado, chame sua função speak polimorficamente por meio do ponteiro base Pet* e, em seguida, libere o pet.

Seu programa receberá uma entrada: um número inteiro que indica qual pet criar.

Exemplo de saída quando a entrada for 0:

Woof!

Exemplo de saída quando a entrada for 1:

Meow!

Exemplo de saída quando a entrada for 2:

Tweet!

A vantagem do padrão Factory é que main.c não precisa conhecer as estruturas Dog, Cat ou Bird. Ele trabalha apenas com o tipo base Pet. Adicionar um novo tipo de pet posteriormente significa adicionar um novo valor ao enum e um novo caso na fábrica, sem alterar nenhum código que use pets.

Experimente você mesmo

#include <stdio.h>
#include "pet.h"

int main(void) {
    int type;
    scanf("%d", &type);
    
    // TODO: Use a fábrica para criar o animal de estimação adequado
    // Dica: Converta o int para PetType
    
    // TODO: Chame a função speak de forma polimórfica por meio do ponteiro Pet*
    
    // TODO: Libere a memória do animal de estimação
    
    return 0;
}
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 C online