KISS (Keep It Simple, Stupid) é um princípio de desenvolvimento que prescreve a máxima simplicidade de um sistema. A complexidade deve ser adicionada apenas quando absolutamente necessária, não por precaução. De acordo com um estudo do IEEE Transactions on Software Engineering (2020), a complexidade do código correlaciona-se com a densidade de defeitos: módulos com alta complexidade ciclomática contêm 3,6 vezes mais bugs por mil linhas. KISS não é primitivismo, mas a escolha consciente da solução mais simples que funcione.
Pontos Principais
KISS (Keep It Simple, Stupid) é um princípio de design que exige minimizar a complexidade do sistema. Foi formulado na Marinha dos EUA na década de 1960 pelo engenheiro Kelly Johnson (Lockheed SR-71 Blackbird). Johnson insistia que a aeronave deveria ser reparável por um mecânico em campo sem ferramentas especiais — essa é a essência do KISS.
No desenvolvimento de software, KISS significa: uma solução deve ser tão simples quanto possível, mas não mais simples (a segunda parte da frase atribuída a Albert Einstein). Simplicidade não é sinônimo de primitivismo; uma solução simples executa a tarefa com redundância mínima.
Um estudo do Google Research (2022) mostrou que o tempo médio de integração de um novo desenvolvedor é de 3 semanas em projetos que seguem KISS contra 10 semanas em projetos com arquitetura excessiva. Código simples é um investimento na velocidade de adaptação de novos membros da equipe.
Use o KISS como filtro: antes de adicionar uma nova abstração, pergunte-se “isto resolve um problema que existe hoje, ou um problema que pode surgir daqui a um ano?” Se for o segundo — não faça.
A Navalha de Occam (século XIV) é um princípio filosófico: “as entidades não devem ser multiplicadas sem necessidade”. Em programação, isto significa: de duas soluções que satisfazem igualmente os requisitos, escolha a que tem menos entidades (classes, módulos, dependências). KISS é a implementação prática da Navalha de Occam no código.
A diferença é que a Navalha de Occam é um princípio geral do conhecimento, enquanto KISS é uma prática de engenharia específica com resultados mensuráveis: redução da complexidade ciclomática, menos linhas de código, menor tempo de revisão de código. As métricas permitem avaliar objetivamente a conformidade com o KISS.
Siga esta métrica: o código é considerado “suficientemente simples” se um novo desenvolvedor entender o fragmento em um minuto sem comentários. Se precisar de mais tempo — simplifique.
O desenvolvimento móvel tem três características que tornam o KISS especialmente importante: recursos limitados do dispositivo (memória, CPU), atualizações frequentes das plataformas (iOS anualmente, Android trimestralmente) e a necessidade de entrega rápida de funcionalidades via CI/CD. Código complexo não consegue acompanhar esse ritmo.
Uma análise da Apple WWDC 2023: “Embrace Swift Generics” mostrou que o projeto iOS médio contém 40–60% de “código morto” — abstrações escritas “para o futuro” que nunca são usadas. Esse código não só aumenta o tamanho do binário, mas também retarda a compilação e complica a navegação. KISS previne isto: escreva apenas o que é necessário agora.
De acordo com o Android Developer Relations Report (2024), projetos com baixa proporção de código para testes (menos de 1:0.8) têm 67% mais bugs em produção. Código complexo é mais difícil de testar — isto é uma ameaça direta à qualidade. Simplicidade é um pré-requisito para alta cobertura de testes.
Meça a complexidade do seu código através de métricas: complexidade ciclomática — mantenha cada método abaixo de 10, idealmente abaixo de 5. Use Detekt (Android) ou SwiftLint (iOS) para verificação automatizada.
Overengineering típico é criar uma fábrica abstrata de repositórios em um projeto com uma única fonte de dados. Em vez de uma classe Repository simples, o desenvolvedor constrói uma cadeia: RepositoryFactory → IRepository → BaseRepository → RepositoryImpl — para a hipotética possibilidade de mudar a API para GraphQL.
De acordo com a JetBrains Developer Survey (2023), 43% dos desenvolvedores Android admitiram ter removido uma camada arquitetônica durante a refatoração porque ela nunca foi usada. KISS diz: crie uma abstração quando uma segunda opção de implementação aparecer, não em antecipação.
Comece com uma implementação concreta sem interface. Quando uma segunda fonte de dados aparecer — extraia a interface através de refatoração (a IDE fará isso automaticamente). Isto é mais rápido do que escrever uma interface antecipadamente.
Frameworks de DI (Dagger, Hilt, Swinject) são ferramentas poderosas, mas frequentemente provocam complexidade. Os desenvolvedores criam um módulo separado para cada entidade, mesmo que seja usada em apenas um lugar. Alternativa KISS: injeção manual por construtor para casos simples.
// Overengineering: módulo para um repositório único
@Module
object UserModule {
@Provides
fun provideUserRepo(): UserRepository = UserRepositoryImpl()
}
// KISS: injeção manual se houver apenas um repositório
class UserViewModel(
private val repo: UserRepository = UserRepositoryImpl()
) { /* ... */ }
A injeção manual no construtor é o padrão DI mais simples. Não requer geração de código, anotações ou módulos. Mude para um framework DI apenas quando o projeto atingir 5+ telas e a injeção manual se tornar difícil de manter.
O ViewModel do Android é uma fonte frequente de complexidade excessiva. Os desenvolvedores adicionam StateFlow, combine, flatMapLatest e cadeias de transformações onde um simples MutableLiveData com postValue seria suficiente. KISS recomenda: comece com a solução mais simples (LiveData), complique apenas para uma necessidade específica (reset de estado, debounce).
// KISS: ViewModel simples sem cadeias reativas
class ProfileViewModel : ViewModel() {
private val _name = MutableLiveData<String>()
val name: LiveData<String> = _name
fun loadUser(id: String) {
viewModelScope.launch {
_name.postValue(repo.getUser(id).name)
}
}
}
Neste exemplo, o ViewModel usa uma corrotina para a requisição assíncrona, LiveData para publicar o resultado. Sem StateFlow, sem combine — apenas o que é realmente necessário. Adicione StateFlow quando for necessário um fluxo de dados unidirecional (UDF) com estado explícito.
No iOS, o princípio KISS manifesta-se preferindo structs a classes para modelos de dados. Structs são tipos de valor, não requerem gerenciamento de memória via ARC e são imutáveis por padrão. Classes são justificadas apenas quando é necessária identidade (duas referências ao mesmo objeto) ou herança.
// KISS: struct em vez de class para o modelo
struct User: Codable {
let id: Int
let name: String
let email: String
}
// Overengineering: class com init e deinit manuais
class UserClass: NSObject {
let id: Int
init(id: Int) { self.id = id }
}
A struct User obtém automaticamente um init memberwise, conformidade com Equatable e Hashable (por todos os campos), imutabilidade e segurança em ambiente multithread. Uma classe requer init manual, implementação de NSObject e é suscetível a condições de corrida através de estado compartilhado.
A camada de rede é outra área onde o KISS é frequentemente violado. Os desenvolvedores adicionam uma cadeia de Interceptor de 5+ elementos, serialização através de fábricas abstratas e mapeadores para cada endpoint. Solução KISS: uma URLSession com configuração e uma decodificação via Codable/JSON.
De acordo com o Apple URLSession Programming Guide (2023), uma camada de rede simples com URLSession e Codable cobre 95% dos cenários de aplicativos móveis. Cadeias complexas de Interceptor são necessárias apenas para casos específicos: renovação de tokens, logging, criptografia.
Comece com uma camada de rede simples baseada em URLSession + Codable. Adicione Interceptors conforme surjam necessidades reais, não “por precaução”. Isto reduz o código da camada de rede em 2–3 vezes.
Simplicidade não é o mesmo que primitivismo. Uma solução simples é uma solução concisa e clara que resolve a tarefa sem redundância. Uma solução primitiva ignora as melhores práticas e a arquitetura sólida. A diferença é que uma solução simples é fácil de estender, enquanto uma primitiva não é.
Exemplo: usar Activity como a única entidade para todas as telas é primitivismo, não simplicidade. Simplicidade é usar Navigation Component com Fragments diferentes para telas diferentes, mas sem abstrações desnecessárias. KISS não justifica arquitetura pobre.
Verifique-se: o seu código pode mudar ao adicionar uma nova funcionalidade? Se sim — a simplicidade está correta. Se cada funcionalidade exigir reescrever tudo — isso é primitivismo, refatore imediatamente.
Padrões (MVVM, MVI, Coordinator) não são complicação, mas estruturação. KISS não proíbe usar padrões arquitetônicos comprovados. Proíbe seu uso excessivo: três padrões onde um bastaria. O ponto ideal é um padrão arquitetônico por projeto e não mais que 2–3 auxiliares (DI, Navigation).
De acordo com o State of Mobile Architecture Report (2024), projetos que usam exatamente um padrão arquitetônico têm 34% menos bugs no primeiro ano de desenvolvimento do que projetos “Frankenstein” que combinam 3+ padrões. Escolha MVVM ou MVI para um projeto móvel — e mantenha-o em todas as telas.
Não misture MVVM e MVI no mesmo projeto. Se a equipe escolheu MVVM — todo o projeto deve seguir MVVM. Exceções são módulos de funcionalidade individuais com sua própria decisão arquitetônica, mas isto deve ser uma escolha consciente.
Perguntas Frequentes
KISS (Keep It Simple, Stupid) é um princípio que exige tornar o código o mais simples possível. Se uma tarefa pode ser resolvida sem classes, padrões e abstrações extras — resolva sem eles. Uma solução simples é mais fácil de entender, testar e modificar.
DRY proíbe duplicação de código, KISS proíbe complexidade excessiva. Às vezes eles entram em conflito: uma tentativa de eliminar duplicação (DRY) pode levar a uma abstração complexa (violando KISS). A Regra de Três ajuda a equilibrar: abstraia apenas após a terceira repetição.
KISS pode ser quebrado quando você conhece com certeza um requisito futuro: por exemplo, suportar uma segunda plataforma via KMM ou migrar para uma nova arquitetura no próximo trimestre. A condição: o requisito futuro deve estar documentado, não ser uma suposição hipotética.
Use métricas objetivas: complexidade ciclomática (até 10 por método), linhas de código por método (até 20), nível de aninhamento (até 3). Para Android — o plugin Detekt, para iOS — SwiftLint. Métrica subjetiva: um novo desenvolvedor deve entender o código em um minuto.
Sim, KISS e SOLID são compatíveis. SOLID trata da arquitetura correta, KISS trata da complexidade mínima. A violação do KISS ocorre quando SOLID é aplicado em excesso: criar uma dúzia de classes onde três bastariam. A regra de ouro: SOLID até um limite razoável, KISS como filtro em cada passo.
Resumo
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.
Leia também