Pular para o conteúdo

Lista de Exercícios 004: Factory Method

Exercício 1: Reflexão: quando Factory Method faz diferença?

Seção intitulada “Exercício 1: Reflexão: quando Factory Method faz diferença?”

Explique, em 8–12 linhas, com suas palavras:

  1. Qual é o problema de ter new de classes concretas espalhado pelo código (pense em manutenção, testes e evolução)?
  2. Em quais situações o Factory Method ajuda a aplicar OCP (Open/Closed Principle)?
  3. Dê um exemplo realista (do seu dia a dia de dev) em que você não usaria Factory Method, e justifique por quê (evitar overengineering).

Exercício 2: Anti‑pattern: “fábrica” mal implementada (Java)

Seção intitulada “Exercício 2: Anti‑pattern: “fábrica” mal implementada (Java)”

O objetivo do time era selecionar um tipo de notificador (EMAIL/SMS), mas o resultado ficou difícil de estender e com regras de criação espalhadas.

public class SistemaAlertas {
public void enviarAlerta(String tipo, String mensagem) {
if ("EMAIL".equals(tipo)) {
EmailNotificador n = new EmailNotificador();
n.enviar(mensagem);
} else if ("SMS".equals(tipo)) {
SmsNotificador n = new SmsNotificador();
n.enviar(mensagem);
} else {
throw new IllegalArgumentException("Tipo inválido: " + tipo);
}
}
}
class EmailNotificador {
public void enviar(String msg) {
System.out.println("EMAIL: " + msg);
}
}
class SmsNotificador {
public void enviar(String msg) {
System.out.println("SMS: " + msg);
}
}
  1. Aponte 2 problemas de design nesse código (pense em acoplamento e extensibilidade).
  2. Reescreva a solução usando Factory Method, com:
    • uma interface Notificador;
    • uma classe abstrata SistemaAlertas (Creator) com um método criarNotificador();
    • pelo menos duas subclasses (Concrete Creators) para EMAIL e SMS;
    • o método de alto nível (ex.: enviarAlerta(...)) sem if/else para escolher a classe concreta.
  3. (Opcional) Mostre como você adicionaria PushNotificador sem editar o código do “fluxo principal”.

Exercício 3: Implementação: Factory Method para exportação de relatórios (Java)

Seção intitulada “Exercício 3: Implementação: Factory Method para exportação de relatórios (Java)”

Você está construindo um módulo que exporta relatórios em formatos diferentes.

  1. Crie uma interface ExportadorRelatorio com:
    • String exportar(String conteudo);
    • A implementação deve retornar uma String representando o dado exportado (para simplificar, sem arquivos).
  2. Implemente dois exportadores:
    • ExportadorPDF (retorne algo como "PDF(...)")
    • ExportadorCSV (retorne algo como "CSV(...)")
  3. Crie uma classe abstrata GeradorRelatorio (Creator) contendo:
    • um método gerar(String conteudo) que chama criarExportador() e usa o exportador para exportar;
    • o factory method protected abstract ExportadorRelatorio criarExportador();
  4. Crie dois Concrete Creators:
    • GeradorRelatorioPDF
    • GeradorRelatorioCSV
  5. Escreva uma classe Main demonstrando:
    • gerar o mesmo conteúdo nos dois formatos;
    • imprimir os resultados no console.
  • Adicione ExportadorHTML e um GeradorRelatorioHTML sem alterar as classes existentes (apenas adicionando novas).