O problema que o padrão resolve

Imagine um sistema de notificações que envia e-mail ou SMS. Se a lógica de negócio instancia diretamente EmailNotificador, cada nova forma de envio exige editar o fluxo que deveria apenas preparar e enviar uma notificação. Factory Method define um método de criação cuja implementação escolhe o produto concreto, mantendo o código cliente dependente de uma abstração.

Exemplo em C#

public interface IExportador
{
    string Exportar(string conteudo);
}

public abstract class Relatorio
{
    public string Gerar(string dados)
    {
        var exportador = CriarExportador();
        return exportador.Exportar(dados);
    }

    protected abstract IExportador CriarExportador();
}

public sealed class RelatorioCsv : Relatorio
{
    protected override IExportador CriarExportador() => new CsvExportador();
}

public sealed class RelatorioJson : Relatorio
{
    protected override IExportador CriarExportador() => new JsonExportador();
}

O método Gerar define o fluxo estável e chama uma fábrica extensível. Em uma aplicação moderna, a variação pode ser selecionada pela composição de dependências em vez de uma hierarquia de subclasses; preserve a intenção sem copiar o desenho clássico se DI já resolver o problema com menos código.

Quando usar e quando evitar

Use quando subclasses ou implementações realmente variam o tipo criado e o fluxo cliente não deve conhecer essa escolha. Evite quando há apenas uma implementação ou quando um construtor simples já deixa a intenção mais clara. O padrão desloca a decisão; não elimina a necessidade de decidir configuração e ciclo de vida.

Relação com outros padrões

Abstract Factory cria famílias de produtos relacionados; Factory Method decide um tipo de produto por método de criação. Builder resolve construção passo a passo, não seleção de família. Veja também o guia dos 23 Design Patterns GoF e os princípios de SOLID.