Menu
Coddy logo textTech

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 o código de malloc e de inicialização por todo o programa, você chama uma função que decide o que criar e retorna um objeto pronto para uso.

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

Esta é 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. O chamador não precisa saber sobre Circle ou Rectangle. Ele simplesmente trabalha com o tipo base:

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

Este padrão facilita a adição de 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 Animais: um sistema que cria diferentes tipos de animais de estimação 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ê a centralizará em um único lugar que decide que tipo de animal criar com base em um identificador de entrada.

Você 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 struct base Pet que contenha um ponteiro de função para 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 a limpeza.
  • pet.c: Defina três structs concretas de animais, 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 animal 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 inteiro que represente o tipo de animal (0 para cachorro, 1 para gato, 2 para pássaro). Use sua fábrica para criar o animal apropriado, chame sua função speak polimorficamente por meio do ponteiro base Pet* e, em seguida, libere o animal.

Seu programa receberá uma entrada: um inteiro indicando qual animal criar.

Exemplo de saída quando a entrada é 0:

Woof!

Exemplo de saída quando a entrada é 1:

Meow!

Exemplo de saída quando a entrada é 2:

Tweet!

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

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 pet apropriado
    // Dica: Faça o cast do int para PetType
    
    // TODO: Chame a função speak polimorficamente através do ponteiro Pet*
    
    // TODO: Libere o pet
    
    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