Lista de Exercícios 005: Abstract Factory
Exercício 1: Reflexão
Seção intitulada “Exercício 1: Reflexão”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:
- Por que o Abstract Factory é apropriado (ou não) para esse cenário.
- Como o padrão ajuda a evitar “mistura” de objetos de famílias diferentes.
- Quais custos (trade-offs) você espera ao adotar esse padrão (em classes, manutenção e extensibilidade).
Exercício 2: Código com má implementação
Seção intitulada “Exercício 2: Código com má implementação”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.
Código inicial (ruim)
Seção intitulada “Código inicial (ruim)”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(); } }}Exercício 3: Implementação (Java)
Seção intitulada “Exercício 3: Implementação (Java)”Implemente Abstract Factory para um sistema de exportação de relatórios com duas famílias:
- HTML
Cada família deve ser capaz de criar dois produtos:
ReportHeader(cabeçalho)ReportBody(corpo)
Requisitos
Seção intitulada “Requisitos”- Defina interfaces:
ExporterFactory(métodoscreateHeader()ecreateBody())ReportHeader(métodoString render())ReportBody(métodoString render())
- Implemente as famílias concretas:
PdfExporterFactory,PdfHeader,PdfBodyHtmlExporterFactory,HtmlHeader,HtmlBody
- Crie uma classe cliente
ReportRendererque recebeExporterFactorye monta o relatório:- saída final:
header.render() + "\n" + body.render()
- saída final:
- Demonstre o uso com um
maincriando um relatório em PDF e outro em HTML.