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

Este padrão usa herança e métodos abstratos. A classe base contém um "método de modelo" que chama uma sequência de etapas, algumas das quais são abstratas e devem ser implementadas pelas subclasses:

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");
}

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
// Saving to default location

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

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.

challenge icon

Desafio

Fácil

Vamos criar 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 inventário) 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 maneira diferente.

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

  • ReportGenerator.cs: Crie uma classe abstrata ReportGenerator no namespace Reporting. Essa classe base define o esqueleto do algoritmo de geração de relatórios por meio 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 maneira 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 concretas de relatório no mesmo namespace que herdem 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 dos relatórios e gerando-os. 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órios apropriado com base na entrada e chame seu método Generate().

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

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

Se a entrada for inventory, a saída deverá 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. SalesReport usa o comportamento de saída padrão, enquanto InventoryReport o sobrescreve — demonstrando como o padrão Template Method permite controlar quais etapas são obrigatórias de sobrescrever e quais podem ser personalizadas opcionalmente!

Experimente você mesmo

using System;
using Reporting;

class Program
{
    public static void Main(string[] args)
    {
        string reportType = Console.ReadLine();
        
        // TODO: Crie o gerador de relatório apropriado com base em 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

Pratique por conta própria: Compilador de C# online