Design de software

Diferenças entre Strategy, Template Method e Command

Você já passou por isto ao estudar padrões de projeto?

4 min de leitura
Imagem de capa de Diferenças entre Strategy, Template Method e Command

Você já passou por isto ao estudar padrões de projeto?

“Qual é a diferença entre Strategy e Template Method? E por que Command entrou nessa?”

Os três parecem trocar comportamentos, então é fácil confundi-los.

Vamos ao ponto principal.

Strategy troca o algoritmo inteiro,

Template Method mantém a estrutura e altera apenas algumas etapas,

e Command encapsula a “ação a ser executada” em um objeto para executá-la depois.

Entendendo essa frase, metade do caminho está feita. Hoje vamos diferenciar os três padrões com código.


Três padrões: qual é a diferença?

Vamos organizar a visão geral em uma tabela.

Categoria Padrão Strategy Template Method Padrão Command
Essência Trocar o algoritmo inteiro Estrutura fixa, trocar algumas etapas Encapsular o comportamento em um objeto
Reutilização Composição (delegação) Herança Composição (delegação)
Momento da troca Tempo de execução Tempo de compilação (herança) Tempo de execução
Foco principal “Como calcular?” “Quando a ordem é igual, mas os detalhes mudam” “Quando e o que executar?”

É aqui que surge a confusão.

Os três têm o mesmo objetivo: separar as partes que mudam.

Mas o modo e o objetivo da separação são diferentes. Vamos analisar um por um.


Strategy troca o algoritmo inteiro

Strategy transforma diferentes formas de fazer a mesma coisa em objetos independentes, trocados quando necessário.

Meios de pagamento são um exemplo perfeito.

Cartão, KakaoPay ou transferência bancária: o objetivo (pagar) é o mesmo, mas o método muda.

Esta é a estrutura de troca completa do Strategy
Esta é a estrutura de troca completa do Strategy
protocol PayStrategy {
    func pay(_ amount: Int) -> String
}
struct CardPay: PayStrategy {
    func pay(_ amount: Int) -> String { "Pagamento com cartão \(amount)" }
}
struct KakaoPay: PayStrategy {
    func pay(_ amount: Int) -> String { "Pagamento com KakaoPay \(amount)" }
}

var strategy: PayStrategy = CardPay()
print(strategy.pay(10000))
// Saída: pagamento com cartão 10000

O ponto é que trocar a variável strategy por KakaoPay() em tempo de execução substitui todo o comportamento.

A ideia é delegar por composição (composition), em vez de usar herança.

Ao escrever o código da estratégia de pagamento, a estrutura de delegação fica clara
Ao escrever o código da estratégia de pagamento, a estrutura de delegação fica clara

Template Method mantém a estrutura e troca apenas uma parte

Template Method segue uma linha um pouco diferente.

A ordem do fluxo inteiro é fixa, mas as subclasses preenchem algumas etapas.

Pense em fazer miojo: ferver a água → adicionar ingredientes → finalizar. A ordem é igual; só muda “adicionar ingredientes”.

class Ramen {
    func cook() {           // Isto é Template Method
        boilWater()
        addIngredients()    // Somente esta etapa é trocada na subclasse
        print("Concluído!")
    }
    func boilWater() { print("Ferver a água") }
    func addIngredients() { print("Ingredientes básicos") }
}
class CheeseRamen: Ramen {
    override func addIngredients() { print("Adicionar queijo") }
}
CheeseRamen().cook()
// Saída: ferver a água / adicionar queijo / concluído!

A diferença decisiva para Strategy é usar herança e trocar apenas algumas etapas, não tudo.

A classe-pai controla o fluxo (cook).


Command encapsula o comportamento a ser executado

Command tem uma preocupação totalmente diferente dos dois anteriores.

Não é sobre como calcular, mas sobre transformar a ação em objeto para executá-la, cancelá-la ou enfileirá-la depois.

Pense nos botões de um controle remoto. O botão guarda o comando “acender a luz” em um objeto e o executa quando pressionado.

protocol Command { func execute() }
struct LightOn: Command {
    func execute() { print("Acender a luz") }
}

let button: Command = LightOn()
button.execute()   // Eu decido quando executar
// Saída: acender a luz

Como a requisição foi encapsulada em um objeto, é natural adicionar undo, logs e filas de tarefas.

Em resumo: Strategy escolhe o método; Command armazena e gerencia a requisição.


Quando usar e quando evitar

No trabalho, costumo escolher com estes critérios.

  • Padrão Strategy: há vários algoritmos para o mesmo objetivo e é preciso trocá-los em tempo de execução (ordenação, descontos, pagamentos)
  • Template Method: a ordem do processamento é sempre igual e só algumas etapas mudam (fluxo de parsing, turnos de jogo)
  • Command: é preciso adiar, cancelar, refazer ou enfileirar a execução (desfazer, agendador de tarefas)

Também há sinais de que devemos evitar esses padrões.

Se há apenas dois ou três ramos e eles não vão crescer, não force um padrão. Um simples if será mais legível.

Especialmente por depender de herança, Template Method pode ser rígido; se flexibilidade importa, considere primeiro Strategy (composição).


Como isso aparece em entrevistas

P. Qual é a maior diferença entre Strategy e Template Method?

Strategy troca o algoritmo inteiro em tempo de execução por composição (delegação); Template Method fixa a estrutura por herança e sobrescreve apenas algumas etapas. Strategy é mais flexível; Template Method controla melhor o fluxo.

P. Em que Command difere de Strategy?

Strategy foca em escolher o método; Command encapsula a própria requisição em um objeto e permite undo, enfileiramento e logs. Um trata da escolha do algoritmo; o outro, do gerenciamento da requisição.


Embora pareçam semelhantes, basta observar o que é separado e por quê para distingui-los.

Strategy é o método; Template Method são as lacunas no fluxo; Command é a própria requisição. Lembre dessas três palavras e você não vai mais confundi-los. Bons estudos!

Continue lendo