Menu
Coddy logo textTech

Padrão Factory

Parte da seção Programação Orientada a Objetos do Journey de PHP da Coddy. Lição 72 de 91.

O Factory Pattern é um padrão de projeto criacional que delega a criação de objetos a uma classe ou método separado. Em vez de usar new diretamente em todo o seu código, você solicita a uma factory que crie os objetos para você.

Este padrão é particularmente útil quando você tem várias classes relacionadas que compartilham uma interface comum e deseja decidir qual delas instanciar com base em alguma condição. Considere um sistema de notificações que pode enviar mensagens por diferentes canais:

<?php
interface Notification {
    public function send(string $message): string;
}

class EmailNotification implements Notification {
    public function send(string $message): string {
        return "Email: $message";
    }
}

class SmsNotification implements Notification {
    public function send(string $message): string {
        return "SMS: $message";
    }
}

Sem uma fábrica, você espalharia instruções if e chamadas new por toda parte. A fábrica centraliza essa lógica:

<?php
class NotificationFactory {
    public static function create(string $type): Notification {
        return match($type) {
            'email' => new EmailNotification(),
            'sms' => new SmsNotification(),
            default => throw new InvalidArgumentException("Unknown type: $type")
        };
    }
}

$notification = NotificationFactory::create('email');
echo $notification->send('Hello!');

Saída:

Email: Hello!

O principal benefício é que seu código depende da interface Notification, não de classes concretas. Se você adicionar posteriormente uma classe PushNotification, precisará atualizar apenas a fábrica. Todo o código que usa a fábrica terá acesso automaticamente ao novo tipo, sem modificações.

challenge icon

Desafio

Fácil

Vamos criar um sistema gerador de documentos usando o Padrão Factory. Diferentes tipos de documento (PDF, HTML, Texto simples) compartilham uma interface comum, mas produzem saídas diferentes: um cenário perfeito para centralizar a criação de objetos em uma factory.

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

  • Document.php: Crie uma interface Document que define o contrato que todos os tipos de documento devem seguir. Ela deve ter um único método render(string $content): string que recebe o conteúdo e retorna a saída do documento formatada.
  • Documents.php: Inclua a interface Document e crie três classes que a implementem:
    • PdfDocument: Seu método render() retorna "PDF: [content]"
    • HtmlDocument: Seu método render() retorna "<html>[content]</html>"
    • TextDocument: Seu método render() retorna "TXT: [content]"
  • DocumentFactory.php: Inclua o arquivo Documents e crie uma classe DocumentFactory com um método estático create(string $type): Document. Esse método deve usar match para retornar o objeto de documento apropriado com base no tipo:
    • "pdf" retorna um novo PdfDocument
    • "html" retorna um novo HtmlDocument
    • "text" retorna um novo TextDocument
    • Qualquer outro tipo deve lançar uma InvalidArgumentException com a mensagem "Unknown document type: [type]"
  • main.php: Inclua o arquivo DocumentFactory. Você receberá duas entradas: um tipo de documento e o conteúdo a ser renderizado.

    Use a factory para criar o tipo de documento apropriado, depois chame seu método render() com o conteúdo e imprima o resultado.

    Em uma nova linha, imprima "Factory benefit: Adding new types only requires updating the factory" para destacar por que esse padrão é valioso.

O Padrão Factory mantém seu código flexível. Quando você precisar adicionar um MarkdownDocument futuramente, atualizará apenas a factory, enquanto todo o código existente continuará funcionando sem alterações.

Experimente você mesmo

<?php
require_once 'DocumentFactory.php';

// Ler entrada
$type = trim(fgets(STDIN));
$content = trim(fgets(STDIN));

// TODO: Use DocumentFactory para criar o tipo de documento apropriado
// TODO: Chame o método render() com o conteúdo e imprima o resultado
// TODO: On a new line, print "Factory benefit: Adding new types only requires updating the factory"

?>
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 PHP online