Menu
Coddy logo textTech

Padrão Template Method

Parte da seção Programação Orientada a Objetos do Journey de C# da Coddy — lição 59 de 70.

O padrão Template Method é um padrão comportamental que define o esqueleto de um algoritmo em uma classe base, permitindo que as subclasses sobrescrevam etapas específicas sem alterar a estrutura geral. A classe base controla o fluxo de trabalho, enquanto as classes derivadas customizam partes individuais.

Este padrão utiliza herança e métodos abstratos. A classe base contém um "template method" que chama uma sequência de passos, alguns dos quais são abstratos e devem ser implementados pelas subclasses:

public abstract class DataProcessor
{
    // Template method - define a estrutura do algoritmo
    public void Process()
    {
        ReadData();
        ProcessData();
        SaveData();
    }
    
    protected abstract void ReadData();
    protected abstract void ProcessData();
    protected virtual void SaveData() => Console.WriteLine("Saving to default location");
}

public class CsvProcessor : DataProcessor
{
    protected override void ReadData() => Console.WriteLine("Reading CSV file");
    protected override void ProcessData() => Console.WriteLine("Parsing CSV data");
}

public class JsonProcessor : DataProcessor
{
    protected override void ReadData() => Console.WriteLine("Reading JSON file");
    protected override void ProcessData() => Console.WriteLine("Parsing JSON data");
    protected override void SaveData() => Console.WriteLine("Saving to cloud");
}

Cada subclasse fornece sua própria implementação, enquanto a classe base impõe a ordem das operações:

DataProcessor csv = new CsvProcessor();
csv.Process();
// Lendo arquivo CSV
// Analisando dados CSV
// Salvando no local padrão

DataProcessor json = new JsonProcessor();
json.Process();
// Lendo arquivo JSON
// Analisando dados JSON
// Salvando na nuvem

O padrão Template Method é ideal quando múltiplas classes compartilham a mesma estrutura de algoritmo, mas diferem em passos específicos. Ele promove a reutilização de código ao colocar a lógica comum na classe base, permitindo flexibilidade por meio de métodos que podem ser sobrescritos.

challenge icon

Desafio

Fácil

Vamos construir um sistema de geração de relatórios usando o padrão Template Method. Diferentes tipos de relatórios (como relatórios de vendas e relatórios de estoque) compartilham a mesma estrutura geral - todos precisam coletar dados, formatá-los e gerar o resultado - mas cada tipo de relatório lida com essas etapas de forma diferente.

Você organizará seu código em três arquivos:

  • ReportGenerator.cs: Crie uma classe abstrata ReportGenerator no namespace Reporting. Esta classe base define o esqueleto do algoritmo de geração de relatório através de um método template chamado Generate(). O método deve chamar três etapas em ordem: GatherData(), FormatReport() e OutputReport(). Torne GatherData() e FormatReport() abstratos (cada tipo de relatório os implementará de forma diferente), enquanto OutputReport() deve ser um método virtual com uma implementação padrão que imprime Sending to default printer.
  • ConcreteReports.cs: Crie duas classes de relatório concretas no mesmo namespace que herdam de ReportGenerator:
    • SalesReport - implementa GatherData() para imprimir Collecting sales data from database e FormatReport() para imprimir Formatting as sales summary
    • InventoryReport - implementa GatherData() para imprimir Scanning warehouse inventory, FormatReport() para imprimir Formatting as inventory list, e sobrescreve OutputReport() para imprimir Sending to warehouse manager
  • Program.cs: Reúna tudo criando instâncias de relatório e gerando-as. O método template garante que cada relatório siga o mesmo processo de três etapas, mas o comportamento específico de cada etapa varia de acordo com o tipo de relatório.

Você receberá uma entrada:

  • O tipo de relatório: sales ou inventory

Crie o gerador de relatório apropriado com base na entrada e chame seu método Generate().

Por exemplo, se a entrada for sales, a saída deve ser:

Collecting sales data from database
Formatting as sales summary
Sending to default printer

Se a entrada for inventory, a saída deve ser:

Scanning warehouse inventory
Formatting as inventory list
Sending to warehouse manager

Observe como ambos os relatórios seguem exatamente a mesma estrutura de algoritmo (coletar, formatar, gerar), mas a implementação de cada etapa é personalizada. O SalesReport usa o comportamento de saída padrão, enquanto o InventoryReport o sobrescreve - demonstrando como o padrão Template Method permite controlar quais etapas são obrigatórias para sobrescrever e quais podem ser opcionalmente personalizadas!

Folha de consulta

O padrão Template Method 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 contém um "método template" que chama uma sequência de etapas. Algumas etapas são abstratas (devem ser implementadas pelas subclasses), enquanto outras podem ser virtuais (opcionais para sobrescrever):

public abstract class DataProcessor
{
    // Método template - define a estrutura do algoritmo
    public void Process()
    {
        ReadData();
        ProcessData();
        SaveData();
    }
    
    protected abstract void ReadData();
    protected abstract void ProcessData();
    protected virtual void SaveData() => Console.WriteLine("Saving to default location");
}

As subclasses fornecem suas próprias implementações enquanto a classe base impõe a ordem das operações:

public class CsvProcessor : DataProcessor
{
    protected override void ReadData() => Console.WriteLine("Reading CSV file");
    protected override void ProcessData() => Console.WriteLine("Parsing CSV data");
}

public class JsonProcessor : DataProcessor
{
    protected override void ReadData() => Console.WriteLine("Reading JSON file");
    protected override void ProcessData() => Console.WriteLine("Parsing JSON data");
    protected override void SaveData() => Console.WriteLine("Saving to cloud");
}

Uso:

DataProcessor csv = new CsvProcessor();
csv.Process();
// Reading CSV file
// Parsing CSV data
// Saving to default location

DataProcessor json = new JsonProcessor();
json.Process();
// Reading JSON file
// Parsing JSON data
// Saving to cloud

O padrão Template Method é ideal quando várias classes compartilham a mesma estrutura de algoritmo, mas diferem em etapas específicas. Ele promove a reutilização de código ao colocar a lógica comum na classe base, permitindo flexibilidade por meio de métodos que podem ser sobrescritos.

Experimente você mesmo

using System;
using Reporting;

class Program
{
    public static void Main(string[] args)
    {
        string reportType = Console.ReadLine();
        
        // TODO: Criar o gerador de relatório apropriado com base no reportType
        // Se reportType for "sales", crie um SalesReport
        // Se reportType for "inventory", crie um InventoryReport
        // Em seguida, chame o método Generate() no relatório
        
    }
}
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