Boilerplate no desenvolvimento de aplicativos: o que é, exemplos e como reduzir

Autor: IT Sectr Publicado: 2026-07-26 Tempo de leitura: 10 min

Boilerplate é o código repetitivo que os desenvolvedores escrevem com mudanças mínimas em cada novo módulo ou projeto. Ele não contém lógica de negócios única, mas simplesmente prepara a infraestrutura: configuração, importação de bibliotecas, manipuladores padrão e classes DTO. De acordo com o CodeScene Engineering Productivity Report (2025), o boilerplate constitui de 20 a 40 por cento de todo o código em um aplicativo comercial típico. O principal problema desse código não é que ele se repete, mas que cada repetição é um ponto de falha: um erro em uma cópia não se sincroniza com as outras, e os bugs se multiplicam pelo projeto. Automatizar a geração de boilerplate através de geração de código, anotações e macros é uma das maneiras mais eficazes de acelerar o desenvolvimento sem perder qualidade.

Pontos principais

  • Boilerplate — código repetitivo que se repete de módulo a módulo sem alterações na lógica de negócios.
  • Principais fontes: configuração de DI, classes DTO, telas com formulários, requisições de rede e mapeamento ORM.
  • O boilerplate retarda o desenvolvimento e aumenta o número de erros ao copiar.
  • Ferramentas de redução: geração de código, anotações (Lombok, classes Data), macros e geradores de telas.
  • O objetivo não é eliminar o boilerplate completamente, mas automatizar sua criação e sincronização.

O que é Boilerplate?

Código boilerplate são fragmentos de código fonte que se repetem em diferentes partes do projeto com variações mínimas. O termo vem da indústria gráfica, onde boilerplate se referia a blocos de texto pré-escritos para jornais que não precisavam ser reescritos. Em programação, é qualquer código que você é forçado a escrever repetidamente para atender aos requisitos do framework, linguagem ou arquitetura.

Boilerplate não é dívida técnica no sentido clássico — não contém bugs e não viola os princípios SOLID. No entanto, aumenta a quantidade de código que precisa ser mantida, testada e lida. Cada linha de boilerplate é um local potencial para um erro de digitação que o compilador nem sempre consegue detectar.

De acordo com o relatório JetBrains Developer Ecosystem (2025), 67 por cento dos desenvolvedores consideram o boilerplate a principal causa de redução de produtividade. No desenvolvimento móvel, esse número é maior: projetos Android em Java contêm uma quantidade significativa de código repetitivo para findViewById, Intents, adaptadores RecyclerView e ContentProviders. Kotlin e Swift resolveram parte desses problemas com meios sintáticos, mas o boilerplate não desapareceu completamente.

Ao projetar a arquitetura, tente escolher soluções que minimizem o código repetitivo. Por exemplo, em vez de escrever manualmente a implementação Parcelable, use @Parcelize em Kotlin. Em vez de fábricas para ViewModel — Hilt com @HiltViewModel. Cada otimização dessas economiza horas de desenvolvimento na escala do projeto.

Exemplos de Boilerplate em projetos móveis

O exemplo mais reconhecível de boilerplate no desenvolvimento Android é o RecyclerView.Adapter. Antes do Kotlin e ViewBinding, cada adaptador exigia cerca de 80–100 linhas de código repetitivo: onCreateViewHolder, onBindViewHolder, getItemCount, classe ViewHolder interna, construtor, vinculação de campos. Com ViewBinding o código reduziu, mas não desapareceu completamente.

Boilerplate de Adapter sem otimizações

kotlin
class UserAdapter(
    private val users: List<User>
) : RecyclerView.Adapter<UserAdapter.ViewHolder>() {

    override fun onCreateViewHolder(
        parent: ViewGroup,
        viewType: Int
    ): ViewHolder {
        val view = LayoutInflater
            .from(parent.context)
            .inflate(R.layout.item_user, parent, false)
        return ViewHolder(view)
    }

    override fun onBindViewHolder(
        holder: ViewHolder,
        position: Int
    ) {
        holder.bind(users[position])
    }

    override fun getItemCount(): Int = users.size

    class ViewHolder(itemView: View) :
        RecyclerView.ViewHolder(itemView) {
        fun bind(user: User) {
            Glide.with(itemView)
                .load(user.avatarUrl)
                .into(itemView.avatar)
        }
    }
}

Outro exemplo ilustrativo é o mapeamento JSON em Java sem bibliotecas. Analisar manualmente uma resposta de API requer escrever dezenas de métodos, cada um verificando a existência de uma chave, obtendo o valor e atribuindo a um campo. Com bibliotecas como Gson, Moshi ou Kotlin Serialization — é uma anotação @Serializable.

No desenvolvimento iOS, o boilerplate clássico é a implementação de CodingKey e Decodable para cada resposta de API, especialmente quando as chaves JSON diferem dos nomes de propriedades em camelCase. Apesar da geração automática de Codable, a enumeração manual de CodingKeys continua sendo uma fonte de código repetitivo.

Use geração de código para criar boilerplate em tempo de compilação. No Android — Annotation Processing (KSP) para Room, Dagger, Moshi. No iOS — Sourcery para Codable e AutoMockable. Para cada hora gasta na configuração da geração, você economiza dias de cópia manual.

Por que o código repetitivo é prejudicial

Boilerplate prejudica o projeto de três maneiras: retarda a escrita de novas funcionalidades, complica a leitura do código existente e cria pontos de dessincronização durante as alterações.

A lentidão no desenvolvimento é óbvia: o desenvolvedor gasta tempo escrevendo código que não contém lógica de negócios. Em vez de implementar um novo recurso (por exemplo, adicionar um campo ao perfil do usuário), ele escreve uma migração de BD, classe DTO, mapper para entidade de domínio, tela com campo de entrada, validação e testes para cada camada. A maior parte desse trabalho é mecânica.

A dessincronização é um problema mais insidioso. Quando uma estrutura de dados muda em um lugar (por exemplo, um campo é adicionado a uma resposta de API), o desenvolvedor deve atualizar o DTO, mapper, modelo, tela e testes. Se um lugar for omitido, o aplicativo compila, mas falha em tempo de execução ou — pior — exibe dados incorretos sem erro. Quanto mais camadas de boilerplate, maior a probabilidade dessa dessincronização.

Analise o projeto em busca de padrões repetidos. Se você vir três classes idênticas com nomes diferentes — é candidato para geração. Introduza a geração de código como parte da solução arquitetural, não como uma otimização pontual. Ela se paga a cada novo módulo.

Geração de código para automatizar boilerplate

A geração de código é a maneira mais confiável de combater o boilerplate. Em vez de escrever código repetitivo manualmente, o desenvolvedor descreve metadados (anotações, esquemas, configurações), e o gerador cria o código pronto em tempo de compilação.

No ecossistema Android, a ferramenta padrão de geração de código é o KSP (Kotlin Symbol Processing). Ele substitui o obsoleto KAPT e funciona mais rápido devido ao acesso direto ao AST do Kotlin sem gerar stubs Java. KSP é usado por Room (geração de implementações DAO), Moshi (geração de JsonAdapter), Glide (geração de classes de carregamento alvo) e Dagger (geração do grafo DI).

Geração de entidades Room com KSP

kotlin
@Entity(tableName = "users")
data class UserEntity(
    @PrimaryKey val id: Long,
    @ColumnInfo(name = "full_name") val name: String,
    @ColumnInfo(name = "avatar_url") val avatarUrl: String
)

@Dao
interface UserDao {
    @Query("SELECT * FROM users WHERE id = :id")
    suspend fun getById(@Param("id") id: Long): UserEntity?
}

No desenvolvimento iOS, o papel da geração de código é desempenhado pelo Sourcery — uma ferramenta que processa templates Stencil e gera código Swift baseado em anotações em comentários. Cenários típicos: AutoMockable (geração de mocks para testes), AutoCodable (implementação Decodable sem CodingKeys), AutoEquatable e AutoLenses.

Para projetos Flutter, o boilerplate é reduzido por geradores através do build_runner: json_serializable para mapeamento JSON, freezed para modelos imutáveis com copyWith, retrofit_generator para clientes API e injectable_generator para DI. Cada um desses geradores transforma 10–20 linhas de anotações em centenas de linhas de código pronto.

Redução através de anotações e macros

Anotações e macros são uma forma declarativa de dizer ao compilador ou pré-processador qual código gerar. O desenvolvedor não escreve a implementação, apenas marca a intenção, e o gerador transforma a marcação em código pronto.

O exemplo mais marcante é o Lombok em Java (historicamente) e a data class do Kotlin. Data class em Kotlin gera automaticamente equals, hashCode, toString, componentN e copy — em Java isso exigiria cerca de 80 linhas de código escrito à mão ou usar Lombok com @Data. Kotlin resolveu o problema no nível da linguagem, tornando o boilerplate implícito.

Em Swift, um papel similar é desempenhado pelos macros (Swift Macros, introduzidos no Swift 5.9). Em vez de escrever manualmente a implementação Codable, o desenvolvedor marca a struct com @Codable — e o compilador gera o código necessário. Outros macros integrados: @Observable (estado observável), @ResultBuilder (construtores de resultado) e @MainActor (despacho para a thread principal).

swift
@Codable
struct UserProfile {
    let id: Int
    let displayName: String
    let avatarURL: URL
    let bio: String?
}

// @Codable macro generates:
// extension UserProfile: Codable { }
// private enum CodingKeys: String, CodingKey {
//     case id, displayName, avatarURL, bio
// }

Ao escolher entre geração de código e macros, prefira macros se a linguagem os suportar. Macros funcionam no nível do compilador, não requerem configuração de scripts de build, não retardam a compilação (ao contrário do Annotation Processing) e estão sempre sincronizados com o código fonte. Se macros não estiverem disponíveis — use geradores externos via KSP, Sourcery ou build_runner.

Práticas de redução por linguagem

Cada linguagem e plataforma oferece suas próprias ferramentas para minimizar o boilerplate. Abaixo estão práticas específicas para as principais stacks de desenvolvimento móvel.

PlataformaFerramenta / TécnicaO que substitui
Android / Kotlindata classequals, hashCode, toString, copy, componentN
Android / Kotlin@ParcelizeImplementação Parcelable
Android / KotlinViewBinding / DataBindingfindViewById, ButterKnife
iOS / SwiftCodable + macrosParsing manual de JSON, CodingKeys
iOS / SwiftSourceryAutoMockable, AutoEquatable, AutoLenses
Flutter / Dartfreezed + json_serializablecopyWith, classes seladas, equals/hashCode, JSON
Flutter / Dartretrofit_generatorCliente API com requisições e respostas tipadas

Para frontend web (React Native / TypeScript), a principal ferramenta é a geração de tipos a partir da especificação OpenAPI (openapi-typescript, swagger-codegen). Cada endpoint obtém automaticamente uma requisição e resposta tipadas — o desenvolvedor não precisa descrever manualmente interfaces para centenas de chamadas de API.

Introduza a geração de código nas fases iniciais do projeto. Migrar um projeto existente para geradores é mais difícil do que projetar com eles desde o início. Se o projeto já estiver escrito — comece pelo ponto mais doloroso: Java → Kotlin (data class), adaptadores manuais → ListAdapter com DiffUtil, mapeamento JSON manual → Moshi / Kotlin Serialization.

Perguntas frequentes

Como o boilerplate difere da dívida técnica?

Boilerplate não é dívida, mas redundância: o código está correto, mas há excesso. Dívida técnica é uma decisão de compromisso consciente que terá que ser corrigida depois. Boilerplate não requer correção — requer automação.

É sempre ruim ter boilerplate?

Não, em projetos pequenos o boilerplate pode ser justificado pela simplicidade: é imediatamente visível e fácil de alterar. O problema surge em escala — quando há mais de dez módulos semelhantes, a cópia manual deixa de ser eficaz e é hora de introduzir geração.

Qual boilerplate não pode ser automatizado?

Código que depende de serviços externos com lógica não padrão (SDKs personalizados, protocolos proprietários) é difícil de gerar. Nesses casos, o boilerplate é escrito manualmente, mas isolado em módulos separados para minimizar a dispersão no projeto.

Vale a pena usar Lombok em novos projetos Java?

Para novos projetos, é melhor migrar diretamente para Kotlin, onde data class resolve as mesmas tarefas no nível da linguagem. Se o projeto permanecer em Java — Lombok continua sendo o padrão de fato, mas lembre-se de que requer um plugin para IDE e pode conflitar com novas versões do Java.

A geração de código aumenta o tempo de compilação?

Sim, a geração de código adiciona tempo à compilação. KSP funciona mais rápido que KAPT, mas ainda adiciona segundos ou minutos a uma compilação completa. Otimização: use compilações incrementais e cache dos resultados de geração entre compilações.

Resumo

  • Boilerplate — código repetitivo que se repete em cada módulo e não contém lógica de negócios única.
  • Principais fontes: classes DTO, mappers, requisições de rede, adaptadores, configuração DI e entidades ORM.
  • Boilerplate retarda o desenvolvimento, aumenta o risco de dessincronização e complica a leitura do código.
  • O principal método de combate — geração de código via KSP, Sourcery, build_runner ou openapi-typescript.
  • Anotações e macros (data class, Codable, @Parcelize, freezed) automatizam os padrões mais comuns.
  • Escolha a geração de código na etapa de projeto da arquitetura, não como uma otimização tardia.
  • Cada linguagem tem suas próprias ferramentas: Kotlin data class, Swift macros, Dart freezed — use-as por padrão.

Vamos desenvolver um aplicativo móvel chave na mão

A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.

Discutir o projeto

Leia também