Pular para o conteúdo

Lista de Exercícios 005: Abstract Factory

Considere um sistema que precisa suportar múltiplos “fornecedores” de infraestrutura (ex.: AWS e Azure). Para cada fornecedor, o sistema precisa criar um conjunto consistente de objetos:

  • Storage (armazenamento)
  • Queue (fila)
  • Monitor (monitoramento)

Explique:

  1. Por que o Abstract Factory é apropriado (ou não) para esse cenário.
  2. Como o padrão ajuda a evitar “mistura” de objetos de famílias diferentes.
  3. Quais custos (trade-offs) você espera ao adotar esse padrão (em classes, manutenção e extensibilidade).

O código abaixo tenta suportar “tema claro” e “tema escuro” para componentes de UI, mas está acoplado e permite misturar famílias. Refatore para usar Abstract Factory, de modo que o cliente não dependa de classes concretas e a escolha do tema controle toda a família.

class LightButton {
void render() { System.out.println("Botão claro"); }
}
class DarkButton {
void render() { System.out.println("Botão escuro"); }
}
class LightCheckbox {
void toggle() { System.out.println("Checkbox claro"); }
}
class DarkCheckbox {
void toggle() { System.out.println("Checkbox escuro"); }
}
class Screen {
private final String theme; // "light" ou "dark"
Screen(String theme) {
this.theme = theme;
}
void draw() {
// Acoplamento e propenso a mistura se alguém alterar só um dos ifs
if ("dark".equalsIgnoreCase(theme)) {
new DarkButton().render();
} else {
new LightButton().render();
}
if ("dark".equalsIgnoreCase(theme)) {
new DarkCheckbox().toggle();
} else {
new LightCheckbox().toggle();
}
}
}

Implemente Abstract Factory para um sistema de exportação de relatórios com duas famílias:

  • PDF
  • HTML

Cada família deve ser capaz de criar dois produtos:

  • ReportHeader (cabeçalho)
  • ReportBody (corpo)
  1. Defina interfaces:
    • ExporterFactory (métodos createHeader() e createBody())
    • ReportHeader (método String render())
    • ReportBody (método String render())
  2. Implemente as famílias concretas:
    • PdfExporterFactory, PdfHeader, PdfBody
    • HtmlExporterFactory, HtmlHeader, HtmlBody
  3. Crie uma classe cliente ReportRenderer que recebe ExporterFactory e monta o relatório:
    • saída final: header.render() + "\n" + body.render()
  4. Demonstre o uso com um main criando um relatório em PDF e outro em HTML.