Pular para o conteúdo

Boas práticas e padrões · Padrões comportamentais · 4 min de leitura

Template Method

Fixa o roteiro de um algoritmo numa classe base e deixa as subclasses preencherem só os passos que variam.

Exportador → buscarDados()1Exportador → formatar()2Exportador → salvar()3CsvExportador → formatar(): implementaimplementaPdfExportador → formatar()Exportador — exportar(): roteiro fixoExportadorexportar(): roteiro fixobuscarDados() — igual para todosbuscarDados()igual para todosformatar() — variaformatar()variasalvar() — igual para todossalvar()igual para todosCsvExportadorCsvExportadorPdfExportadorPdfExportador

Arraste para o lado para ver o diagrama inteiro.

A ordem dos passos nunca muda; cada formato só escreve o passo que é diferente.

O padrão

A classe base define um método final com a sequência (buscar, formatar, salvar) e chama passos abstratos ou "ganchos" com comportamento padrão. É o "Hollywood principle": não nos chame, nós chamamos você — o framework controla o fluxo.

Onde aparece

Ciclo de vida de Activity e ViewModel no Android, testes com setUp/tearDown, frameworks web com hooks antes e depois da requisição.

Alternativa moderna

Em Kotlin e TypeScript, muitas vezes é mais simples passar os passos variáveis como funções (Strategy) do que criar uma hierarquia. Use herança quando o roteiro for estável e houver vários passos relacionados.

No código

✓ ExemploKotlin
abstract class Exportador {
  // o roteiro: final, ninguém altera a ordem
  fun exportar(filtro: Filtro): Arquivo {
    val dados = buscarDados(filtro)
    val conteudo = formatar(dados)
    return salvar(conteudo, extensao)
  }
  protected abstract val extensao: String
  protected abstract fun formatar(dados: List<Linha>): ByteArray
  protected open fun buscarDados(filtro: Filtro) = repositorio.consultar(filtro)
  private fun salvar(bytes: ByteArray, ext: String) = Arquivo("relatorio.$ext", bytes)
}

class CsvExportador : Exportador() {
  override val extensao = "csv"
  override fun formatar(dados: List<Linha>) = dados.joinToString("\n") { it.campos.joinToString(";") }.toByteArray()
}

Um formato novo (XLSX) só implementa extensão e formatar(); buscar e salvar continuam iguais e testados num lugar só.

Em resumo

Referências

Continue aprendendo

Todos os temas de boas práticas e padrões →