O padrão Template Method é um padrão de design comportamental que tem como objetivo principal definir o esqueleto de um algoritmo dentro de uma operação, adiando alguns passos para as subclasses. Ele permite que subclasses redefinam certas etapas de um algoritmo sem alterar a estrutura geral do algoritmo. O padrão Template Method resolve vários problemas:

  1. Reutilização de Código: Ao centralizar o algoritmo comum em uma classe base, o Template Method promove a reutilização de código. As variações específicas são implementadas em subclasses, evitando a duplicação de código.

  2. Controle de Fluxo do Algoritmo: O Template Method oferece um meio de controlar o fluxo de um algoritmo em um único local, facilitando a manutenção e a compreensão do processo.

  3. Flexibilidade e Personalização: Permite que subclasses forneçam implementações específicas para partes de um algoritmo, oferecendo flexibilidade para personalizar o comportamento de acordo com as necessidades.

  4. Inversão de Controle: Ao inverter o controle, onde a classe base chama métodos das subclasses (em vez de o contrário), o Template Method promove um design mais modular e desacoplado.

Como Funciona

O padrão Template Method envolve os seguintes passos:

  • Uma classe abstrata define o método template, que é uma série de passos, alguns dos quais são métodos abstratos.
  • Os métodos abstratos são implementados pelas subclasses, fornecendo as peculiaridades necessárias para diferentes situações.
  • O método template garante que a estrutura do algoritmo permaneça intacta, enquanto permite variações nos detalhes.

Exemplo

Um exemplo clássico do uso do Template Method é em frameworks onde certas operações seguem um fluxo padrão, mas permitem que o usuário personalize etapas específicas. Por exemplo, um framework de processamento de dados pode ter um processo padrão para ler, processar e salvar dados, mas as subclasses podem definir como os dados são lidos e processados.

Exemplo de Implementação

Vamos criar um exemplo simples do padrão Template Method em Java. Vamos desenvolver um esqueleto para um processo de fabricação de bebidas, como café e chá, onde certas etapas são comuns (como ferver a água) e outras são específicas para cada bebida.

Classe Abstrata Base (Template)

Primeiro, definimos a classe base abstrata com o método template:

public abstract class BebidaCafeinada {
    
    // Método template
    final void prepararReceita() {
        ferverAgua();
        preparar();
        despejarNaXicara();
        adicionarCondimentos();
    }
 
    abstract void preparar();
 
    abstract void adicionarCondimentos();
 
    void ferverAgua() {
        System.out.println("Fervendo água");
    }
 
    void despejarNaXicara() {
        System.out.println("Despejando na xícara");
    }
}

Subclasses Concretas

Implementamos duas subclasses concretas para café e chá:

public class Cafe extends BebidaCafeinada {
 
    @Override
    void preparar() {
        System.out.println("Passando o café");
    }
 
    @Override
    void adicionarCondimentos() {
        System.out.println("Adicionando açúcar e leite");
    }
}
 
public class Cha extends BebidaCafeinada {
 
    @Override
    void preparar() {
        System.out.println("Infundindo o chá");
    }
 
    @Override
    void adicionarCondimentos() {
        System.out.println("Adicionando limão");
    }
}

Utilizando o Template Method

Agora, usamos as classes para preparar as bebidas:

public class Main {
    public static void main(String[] args) {
        BebidaCafeinada meuCafe = new Cafe();
        meuCafe.prepararReceita();
 
        System.out.println();
 
        BebidaCafeinada meuCha = new Cha();
        meuCha.prepararReceita();
    }
}

Neste exemplo, BebidaCafeinada define o método template prepararReceita(), que estabelece o esqueleto do algoritmo para preparar uma bebida cafeinada. As etapas específicas (preparar() e adicionarCondimentos()) são deixadas para as subclasses Cafe e Cha implementarem. Isso permite que o Cafe e o Cha modifiquem partes do algoritmo sem alterar sua estrutura geral, demonstrando a eficácia do padrão Template Method em permitir a personalização de certas etapas de um processo mantendo um esqueleto comum.