---
title: "Template Method"
type: "design-pattern"
slug: "template-method"
url: "http://localhost:3000/pt-br/design-patterns/template-method.md"
category: "Padrões comportamentais"
description: "O Template Method é um padrão de projeto comportamental que define o esqueleto de um algoritmo na superclasse mas deixa as subclasses sobrescreverem etapas específicas do algoritmo sem modificar sua estrutura."
---
# Template Method

> O Template Method é um padrão de projeto comportamental que define o esqueleto de um algoritmo na superclasse mas deixa as subclasses sobrescreverem etapas específicas do algoritmo sem modificar sua estrutura.

## Intent

O **Template Method** é um padrão de projeto comportamental que define o esqueleto de um algoritmo na superclasse mas deixa as subclasses sobrescreverem etapas específicas do algoritmo sem modificar sua estrutura.

## Problem

Imagine que você está criando uma aplicação de mineração de dados que analisa documentos corporativos. Os usuários alimentam a aplicação com documentos em vários formatos (PDF, DOC, CSV), e ela tenta extrair dados significativos desses documentos para um formato uniforme.

A primeira versão da aplicação podia funcionar somente com arquivos DOC. Na versão seguinte, ela era capaz de suportar arquivos CSV. Um mês depois, você a “ensinou” a extrair dados de arquivos PDF.

Classes de mineração de dados continham muito código duplicado.

Em algum momento você percebeu que todas as três classes tem muito código parecido. Embora o código para lidar com vários formatos seja inteiramente diferente em todas as classes, o código para processamento de dados e análise é quase idêntico. Não seria bacana se livrar da duplicação de código, deixando a estrutura do algoritmo intacta?

Havia outro problema relacionado com o código cliente que usou essas classes. Ele tinha muitas condicionais que pegavam um curso de ação apropriado dependendo da classe do objeto processador. Se todas as três classes processantes tiverem uma interface comum ou uma classe base, você poderia eliminar as condicionais no código cliente e usar polimorfismo quando chamar métodos em um objeto sendo processado.

## Solution

O padrão do Template Method sugere que você quebre um algoritmo em uma série de etapas, transforme essas etapas em métodos, e coloque uma série de chamadas para esses métodos dentro de um único _método padrão_. As etapas podem ser tanto `abstratas`, ou ter alguma implementação padrão. Para usar o algoritmo, o cliente deve fornecer sua própria subclasse, implementar todas as etapas abstratas, e sobrescrever algumas das opcionais se necessário (mas não o próprio método padrão).

Vamos ver como isso vai funcionar com nossa aplicação de mineração de dados. Nós podemos criar uma classe base para todos os três algoritmos de processamento. Essa classe define um método padrão que consiste de uma série de chamadas para várias etapas de processamento de documentos.

O método padrão quebra o algoritmo em etapas, permitindo que subclasses sobrescrevam essas etapas mas não o método atual.

A princípio nós podemos declarar todos os passos como `abstratos`, forçando as subclasses a fornecer suas próprias implementações para esses métodos. No nosso caso, as subclasses já tem todas as implementações necessárias, então a única coisa que precisamos fazer é ajustar as assinaturas dos métodos para coincidirem com os da superclasse.

Agora vamos ver o que podemos fazer para nos livrarmos do código duplicado. Parece que o código para abrir/fechar arquivos e extrair/analisar os dados são diferentes para vários formatos de dados, então não tem porque tocar nesses métodos. Contudo, a implementação dessas etapas, tais como analisar os dados brutos e compor relatórios, é muito parecida, então eles podem ser erguidos para a classe base, onde as subclasses podem compartilhar o código.

Como você pode ver, nós temos dois tipos de etapas:

* _etapas abstratas_ devem ser implementadas por cada subclasse
* _etapas opcionais_ já tem alguma implementação padrão, mas ainda podem ser sobrescritas se necessário.

Existe outro tipo de etapa chamado _ganchos_(hooks). Um gancho é uma etapa opcional com um corpo vazio. Um método padrão poderia funcionar até mesmo se um hook não for sobrescrito. Geralmente os hooks são colocados antes e depois de etapas cruciais de algoritmos, fornecendo às subclasses com pontos de extensão adicionais para um algoritmo.

## Structure

1. A **Classe Abstrata** declara métodos que agem como etapas de um algoritmo, bem como o próprio método padrão que chama esses métodos em uma ordem específica. Os passos podem ser declarados como `abstratos` ou ter alguma implementação padrão.
2. As **Classes Concretas** podem sobrescrever todas as etapas, mas não o próprio método padrão.

## Pseudocode

Neste exemplo, o padrão **Template Method** fornece um “esqueleto” para várias ramificações de inteligência artificial de um jogo de estratégia simples.

Classes IA de um jogo simples.

Todas as raças do jogo tem quase o mesmo tipo de unidades e construções. Portanto você pode reutilizar a mesma estrutura de IA para várias raças, enquanto é capaz de sobrescrever alguns dos detalhes. Com essa abordagem, você pode sobrescrever a IA dos Orcs para torná-la mais agressiva, fazer os humanos mais orientados a defesa e fazer os monstros serem incapazes de construir qualquer coisa. Adicionando uma nova raça ao jogo irá necessitar a criação de uma nova subclasse IA e a sobrescrição dos métodos padrão declarados na classe IA base.

// A classe abstrata define um método padrão que contém um
// esqueleto de algum algoritmo composto de chamadas, geralmente
// para operações abstratas primitivas. Subclasses concretas
// implementam essas operações, mas deixam o método padrão em si
// intacto.
class GameAI is
    // O método padrão define o esqueleto de um algoritmo.
    method turn() is
        collectResources()
        buildStructures()
        buildUnits()
        attack()

    // Algumas das etapas serão implementadas diretamente na
    // classe base.
    method collectResources() is
        foreach (s in this.builtStructures) do
            s.collect()

    // E algumas delas podem ser definidas como abstratas.
    abstract method buildStructures()
    abstract method buildUnits()

    // Uma classe pode ter vários métodos padrão.
    method attack() is
        enemy = closestEnemy()
        if (enemy == null)
            sendScouts(map.center)
        else
            sendWarriors(enemy.position)

    abstract method sendScouts(position)
    abstract method sendWarriors(position)

// Classes concretas têm que implementar todas as operações
// abstratas da classe base, mas não podem sobrescrever o método
// padrão em si.
class OrcsAI extends GameAI is
    method buildStructures() is
        if (there are some resources) then
            // Construir fazendas, depois quartéis, e então uma
            // fortaleza.

    method buildUnits() is
        if (there are plenty of resources) then
            if (there are no scouts)
                // Construir peão, adicionar ele ao grupo de
                // scouts (batedores).
            else
                // Construir um bruto, adicionar ele ao grupo
                // dos guerreiros.

    // ...

    method sendScouts(position) is
        if (scouts.length > 0) then
            // Enviar batedores para posição.

    method sendWarriors(position) is
        if (warriors.length > 5) then
            // Enviar guerreiros para posição.

// As subclasses também podem sobrescrever algumas operações com
// uma implementação padrão.
class MonstersAI extends GameAI is
    method collectResources() is
        // Monstros não coletam recursos.

    method buildStructures() is
        // Monstros não constroem estruturas.

    method buildUnits() is
        // Monstros não constroem unidades.

## Applicability

Utilize o padrão Template Method quando você quer deixar os clientes estender apenas etapas particulares de um algoritmo, mas não todo o algoritmo e sua estrutura.

 O Template Method permite que você transforme um algoritmo monolítico em uma série de etapas individuais que podem facilmente ser estendidas por subclasses enquanto ainda mantém intacta a estrutura definida em uma superclasse.

 Utilize o padrão quando você tem várias classes que contém algoritmos quase idênticos com algumas diferenças menores. Como resultado, você pode querer modificar todas as classes quando o algoritmo muda.

 Quando você transforma tal algoritmo em um Template Method, você também pode erguer as etapas com implementações similares para dentro de uma superclasse, eliminando duplicação de código. Códigos que variam entre subclasses podem permanecer dentro das subclasses.

## How to Implement

1. Analise o algoritmo alvo para ver se você quer quebrá-lo em etapas. Considere quais etapas são comuns a todas as subclasses e quais permanecerão únicas.
2. Crie a classe abstrata base e declare o método padrão e o conjunto de métodos abstratos representando as etapas do algoritmo. Contorne a estrutura do algoritmo no método padrão ao executar as etapas correspondentes. Considere tornar o método padrão como `final` para prevenir subclasses de sobrescrevê-lo.
3. Tudo bem se todas as etapas terminarem sendo abstratas. Contudo, alguns passos podem se beneficiar de ter uma implementação padrão. Subclasses não tem que implementar esses métodos.
4. Pense em adicionar ganchos entre as etapas cruciais do algoritmo.
5. Para cada variação do algoritmo, crie uma nova subclasse concreta. Ela _deve_ implementar todas as etapas abstratas, mas _pode_ também sobrescrever algumas das opcionais.

## Pros

* Você pode deixar clientes sobrescrever apenas certas partes de um algoritmo grande, tornando-os menos afetados por mudanças que acontece por outras partes do algoritmo.
* Você pode elevar o código duplicado para uma superclasse.

## Cons

* Alguns clientes podem ser limitados ao fornecer o esqueleto de um algoritmo.
* Você pode violar o _princípio de substituição de Liskov_ ao suprimir uma etapa padrão de implementação através da subclasse.
* Implementações do padrão Template Method tendem a ser mais difíceis de se manter quanto mais etapas eles tiverem.

## Relations with Other Patterns

* O [Factory Method](/pt-br/design-patterns/factory-method) é uma especialização do [Template Method](/pt-br/design-patterns/template-method). Ao mesmo tempo, o _Factory Method_ pode servir como uma etapa em um _Template Method_ grande.
* O [Template Method](/pt-br/design-patterns/template-method) é baseado em herança: ele permite que você altere partes de um algoritmo ao estender essas partes em subclasses. O [Strategy](/pt-br/design-patterns/strategy) é baseado em composição: você pode alterar partes do comportamento de um objeto ao suprir ele como diferentes estratégias que correspondem a aquele comportamento. O _Template Method_ funciona a nível de classe, então é estático. O _Strategy_ trabalha a nível de objeto, permitindo que você troque os comportamentos durante a execução.
## Relations

**Related patterns**

- [Factory Method](/pt-br/design-patterns/factory-method.md)
- [Strategy](/pt-br/design-patterns/strategy.md)

