Padrão Template Method
Parte da seção Programação Orientada a Objetos do Journey de PHP da Coddy. Lição 78 de 91.
O Template Method Pattern é um padrão de projeto comportamental que define o esqueleto de um algoritmo em uma classe base, permitindo que as subclasses substituam etapas específicas sem alterar a estrutura geral. A classe base controla o fluxo de trabalho, enquanto as subclasses personalizam partes individuais.
Considere criar diferentes tipos de documentos.
Todo documento segue o mesmo processo: criar o cabeçalho, adicionar o conteúdo, criar o rodapé. Mas os detalhes de cada etapa variam de acordo com o tipo de documento. O método template define essa sequência, enquanto as subclasses implementam os detalhes.
<?php
abstract class DocumentGenerator {
// O método template - define a estrutura do algoritmo
public final function generate(): string {
$output = $this->createHeader();
$output .= $this->createContent();
$output .= $this->createFooter();
return $output;
}
// Passos a serem implementados pelas subclasses
abstract protected function createHeader(): string;
abstract protected function createContent(): string;
abstract protected function createFooter(): string;
}
class HtmlDocument extends DocumentGenerator {
protected function createHeader(): string {
return "<html><head></head><body>";
}
protected function createContent(): string {
return "<p>Hello World</p>";
}
protected function createFooter(): string {
return "</body></html>";
}
}
class TextDocument extends DocumentGenerator {
protected function createHeader(): string {
return "=== DOCUMENT ===\n";
}
protected function createContent(): string {
return "Hello World\n";
}
protected function createFooter(): string {
return "=== END ===";
}
}
$html = new HtmlDocument();
echo $html->generate() . "\n";
$text = new TextDocument();
echo $text->generate();
Saída:
<html><head></head><body><p>Hello World</p></body></html>
=== DOCUMENT ===
Hello World
=== END ===Observe a palavra-chave final no método de modelo. Isso impede que as subclasses alterem a estrutura do algoritmo. O padrão é ideal quando você tem várias classes que seguem o mesmo fluxo de trabalho, mas diferem nos detalhes de implementação. Adicionar um novo tipo de documento significa criar uma nova subclasse sem alterar o código existente.
Desafio
FácilVamos criar um sistema de geração de relatórios usando o Padrão Template Method. Diferentes tipos de relatórios seguem a mesma estrutura — uma seção de título, uma seção de dados e uma seção de resumo —, mas cada tipo de relatório formata essas seções de maneira diferente. O método template definirá esse fluxo de trabalho, enquanto as subclasses personalizarão cada etapa.
Você organizará seu código em quatro arquivos:
ReportGenerator.php: Crie uma classe abstrataReportGeneratorque define o esqueleto do algoritmo de geração de relatórios. Sua classe deve:- Aceitar um título de relatório em seu construtor (use a promoção de construtor)
- Ter um método público
finalgenerate(): stringque chama três etapas na ordem:createTitle(),createBody()ecreateSummary(), concatenando seus resultados - Declarar três métodos protegidos abstratos que as subclasses devem implementar:
createTitle(): string,createBody(): stringecreateSummary(): string
HtmlReport.php: Inclua o arquivo ReportGenerator e crie uma classeHtmlReportque o estenda. Esse relatório formata a saída como HTML:createTitle()retorna"<h1>[title]</h1>"createBody()retorna"<p>Report data goes here</p>"createSummary()retorna"<footer>End of report</footer>"
PlainTextReport.php: Inclua o arquivo ReportGenerator e crie uma classePlainTextReportque o estenda. Esse relatório usa uma formatação de texto simples:createTitle()retorna"### [title] ###\n"createBody()retorna"Report data goes here\n"createSummary()retorna"--- End of report ---"
main.php: Inclua os dois arquivos de relatório. Você receberá duas entradas: um tipo de relatório ("html"ou"text") e um título de relatório.Com base no tipo de relatório, crie o gerador de relatórios apropriado com o título fornecido. Chame
generate()e imprima o relatório completo.
O Padrão Template Method garante que todos os relatórios sigam a mesma estrutura de três etapas, permitindo que cada tipo de relatório formate suas seções de maneira exclusiva. A palavra-chave final em generate() impede que as subclasses alterem a sequência do algoritmo. Elas só podem personalizar etapas individuais.
Experimente você mesmo
<?php
require_once 'HtmlReport.php';
require_once 'PlainTextReport.php';
// Ler entrada
$reportType = trim(fgets(STDIN));
$reportTitle = trim(fgets(STDIN));
// TODO: Com base no tipo de relatório ("html" ou "text"),
// crie o gerador de relatório apropriado com o título fornecido
// TODO: Chame generate() e imprima o relatório completo
?>Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.
Todas as lições de Programação Orientada a Objetos
1Fundamentos de OOP
Arquivos externosIntrodução à OOPClasses vs. objetosA palavra-chave $thisMétodosPropriedadesConstrutor (__construct)Destrutor (__destruct)Recapitulação - Calculadora simples4Herança
Herança BásicaA Palavra-chave parent::Sobrescrita de MétodosA Palavra-chave finalClasses AbstratasRecapitulação - Hierarquia de Funcionários7Encapsulamento
Público, Protegido, PrivadoModificadores de Acesso em ProfundidadeGetters e SettersOcultação de InformaçõesPromoção de Construtor (8.0)Recapitulação - Sistema de Registros de Alunos10Conceitos Avançados de OOP
Composição vs. HerançaInjeção de DependênciaClasses AnônimasEnums (PHP 8.1)Fibras (PHP 8.1)Análise Profunda da Clonagem de ObjetosGeradores e Iteradores13Padrões de Projeto Parte 2
Padrão CommandPadrão AdapterPadrão DecoratorPadrão Template MethodPadrão StatePadrão CompositePadrão Repository2Namespaces e Autoloading
Introdução a NamespacesA palavra-chave usePadrão de Autoloading PSR-4Autoloader do ComposerRecapitulação - Projeto organizado5Interfaces e Contratos
Introdução às InterfacesImplementando InterfacesImplementação de Múltiplas InterfacesInterface vs Classe AbstrataTipagem com InterfacesRecapitulação - Calculadora de Formas8Métodos Mágicos
Introdução aos Métodos Mágicos__toString e __debugInfo__get, __set, __isset, __unset__call e __callStatic__clone e Clonagem de Objetos__serialize e __unserializeRecapitulação - Coleção Personalizada11Sistema de Tipos e Tratamento de Erros
Declarações de TiposTipos NulosTipos de União e InterseçãoClasses de ExceçãoHierarquia de Exceções PersonalizadaTry, Catch, FinallyRecapitulação - Validador de Formulário14Projeto: Gerenciamento de Biblioteca
Visão Geral do ProjetoClasses de Livros e Usuários3Propriedades de Classes
Propriedades de Instância vs. EstáticasConstantes em ClassesMétodos e Propriedades EstáticosPropriedades Privadas e ProtegidasPropriedades Somente para Leitura (PHP 8.1)Recapitulação - Gerenciador de Contas Bancárias6Polimorfismo
Revisão da Sobrescrita de MétodosPolimorfismo via InterfacesIndicação de Tipos e Tipos UnionVinculação Estática TardiaRecapitulação - Processador de Pagamentos9Traits
Introdução a TraitsUsando Múltiplos TraitsResolução de Conflitos entre TraitsMétodos Abstratos em TraitsTraits vs. Herança12Padrões de Projeto – Parte 1
Introdução aos Padrões de ProjetoPadrão SingletonPadrão FactoryPadrão ObserverPadrão StrategyPratique por conta própria: Compilador de PHP online