Médio TypeScript
Relatório com Template Method
Enunciado
Implemente uma classe abstrata GeradorRelatorio com o método concreto gerar() que chama os métodos abstratos cabecalho(), corpo() e rodape(), todos retornando string. Crie duas subclasses: RelatorioPDF e RelatorioHTML, que retornam textos diferentes para cada parte. O método gerar() deve juntar as três partes com quebras de linha e imprimir o resultado.
Requisitos
GeradorRelatoriodeve ser abstrata e ter o método concretogerar().- As subclasses devem implementar os três métodos abstratos.
- A saída deve conter as três partes separadas por
\n.
Código inicial
abstract class GeradorRelatorio {
gerar(): void {
// chame os métodos abstratos e imprima
}
protected abstract cabecalho(): string;
protected abstract corpo(): string;
protected abstract rodape(): string;
}
// Implemente RelatorioPDF e RelatorioHTML
Saída esperada
=== PDF ===
Conteúdo do PDF
--- Fim PDF ---
=== HTML ===
<div>Conteúdo HTML</div>
<!-- Fim HTML -->
Ver dica
No método gerar(), use console.log com template string e \n para separar as partes. Cada subclasse retorna strings diferentes.
Mostrar solução
abstract class GeradorRelatorio {
gerar(): void {
// Template Method: define a ordem das etapas
const resultado = `${this.cabecalho()}\n${this.corpo()}\n${this.rodape()}`;
console.log(resultado);
}
protected abstract cabecalho(): string;
protected abstract corpo(): string;
protected abstract rodape(): string;
}
class RelatorioPDF extends GeradorRelatorio {
protected cabecalho(): string {
return "=== PDF ===";
}
protected corpo(): string {
return "Conteúdo do PDF";
}
protected rodape(): string {
return "--- Fim PDF ---";
}
}
class RelatorioHTML extends GeradorRelatorio {
protected cabecalho(): string {
return "=== HTML ===";
}
protected corpo(): string {
return "<div>Conteúdo HTML</div>";
}
protected rodape(): string {
return "<!-- Fim HTML -->";
}
}
new RelatorioPDF().gerar();
new RelatorioHTML().gerar();
Passo a passo
- A classe abstrata
GeradorRelatoriodefine o método concretogerar(), que é o Template Method. - Dentro de
gerar(), chamamosthis.cabecalho(),this.corpo()ethis.rodape()na ordem correta, separando por\n. - Os três métodos são declarados como
abstract, sem corpo, forçando as subclasses a implementá-los. RelatorioPDFimplementa cada método retornando strings típicas de PDF.RelatorioHTMLimplementa cada método retornando strings HTML.- No final, criamos instâncias e chamamos
gerar(), que executa o algoritmo definido na base.
Por que funciona
O Template Method fixa a estrutura do algoritmo na classe abstrata, mas delega partes variáveis para as subclasses. Assim, a sequência de geração do relatório é sempre a mesma, mas o conteúdo se adapta ao formato.
Erros comuns
- Declarar
gerar()como abstrato: aí não haveria implementação do esqueleto e o padrão se perderia. - Esquecer de implementar um dos métodos abstratos: erro de compilação.
- Usar
privatenos métodos abstratos: eles precisam ser acessíveis na subclasse, então useprotectedoupublic.
Outra forma de resolver
Poderia usar uma interface com os três métodos e uma função externa que os chama. Mas a classe abstrata mantém a lógica de composição junto com o contrato, o que é mais coeso.
Saída esperada
=== PDF ===
Conteúdo do PDF
--- Fim PDF ---
=== HTML ===
<div>Conteúdo HTML</div>
<!-- Fim HTML -->