Menu
Coddy logo textTech

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 subclasses sobrescrevam etapas específicas sem alterar a estrutura geral. A classe base controla o fluxo de trabalho, enquanto as subclasses customizam partes individuais.

Considere construir diferentes tipos de documentos.

Cada documento segue o mesmo processo: criar cabeçalho, adicionar conteúdo, criar rodapé. Mas as especificidades de cada etapa variam de acordo com o tipo de documento. O template method 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 template. Isso impede que 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 tocar no código existente.

challenge icon

Desafio

Fácil

Vamos construir um sistema de geração de relatórios usando o Template Method Pattern. 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á este fluxo de trabalho enquanto as subclasses personalizam cada etapa.

Você organizará seu código em quatro arquivos:

  • ReportGenerator.php — Crie uma classe abstrata ReportGenerator que define o esqueleto do algoritmo de geração de relatório. 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 final chamado generate(): string que chama três etapas em ordem: createTitle(), createBody() e createSummary(), concatenando seus resultados
    • Declarar três métodos protegidos abstratos que as subclasses devem implementar: createTitle(): string, createBody(): string e createSummary(): string
  • HtmlReport.php — Inclua o arquivo ReportGenerator e crie uma classe HtmlReport que o estenda. Este relatório formata a saída como HTML:
    • createTitle() retorna "<h1>" . $this->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 classe PlainTextReport que o estenda. Este relatório usa formatação de texto simples:
    • createTitle() retorna "### " . $this->title . " ###\n"
    • createBody() retorna "Report data goes here\n"
    • createSummary() retorna "--- End of report ---"
  • main.php — Inclua ambos os 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ório apropriado com o título fornecido. Chame generate() e imprima o relatório completo.

O Template Method Pattern 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 forma exclusiva. A palavra-chave final em generate() impede que as subclasses alterem a sequência do algoritmo — elas só podem personalizar as etapas individuais.

Folha de consulta

O Template Method Pattern 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 contém um template method que controla a sequência do fluxo de trabalho. Este método é normalmente marcado como final para evitar que as subclasses alterem a estrutura do algoritmo.

As subclasses implementam métodos abstratos para personalizar etapas individuais do algoritmo.

<?php
abstract class DocumentGenerator {
    // Template method - define a estrutura do algoritmo
    public final function generate(): string {
        $output = $this->createHeader();
        $output .= $this->createContent();
        $output .= $this->createFooter();
        return $output;
    }
    
    // Etapas abstratas para as subclasses implementarem
    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>";
    }
}

$html = new HtmlDocument();
echo $html->generate();

Características principais:

  • O template method é marcado como final para evitar a modificação da estrutura do algoritmo
  • Métodos abstratos definem pontos de personalização para as subclasses
  • Ideal quando várias classes seguem o mesmo fluxo de trabalho, mas diferem nos detalhes de implementação
  • Adicionar novas variantes requer apenas a criação de novas subclasses sem modificar o código existente

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

?>
quiz iconTeste seus conhecimentos

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