Pular para o conteúdo

Self-Documenting Code: O Código Que Se Explica Sozinho

Em engenharia de software moderna, escrever código funcional não é suficiente. O verdadeiro diferencial está em escrever código legível, compreensível e sustentável ao longo do tempo.

É aqui que entra o conceito de Self-Documenting Code, que se resume em escrever código que:
– Dispensa explicações externas sempre que possível
– Comunica intenção, não apenas implementação;
– reduz a necessidade de comentários desnecessários;


A ideia central é simples: O código deve ser a documentação.

De acordo com Robert C. Martin, em Clean Code: A Handbook of Agile Software Craftsmanship, comentários devem ser tratados como um “code smell”, indicando falhas na expressividade do código:

“Comentários são falhas no código. Se você precisa comentar, talvez o código não esteja claro o suficiente.”

Código difícil de entender:
– Aumenta o custo mental de manutenção
– Dificulta evolução e refatoração
– Compromete a escalabilidade

Ou seja, escrever código claro não é apenas estética, é engenharia de longo prazo.

Exemplos práticos em C#

1. Nomes significativos
Ruim:

var x = d * 0.85;

Bom:

decimal discountedPrice = originalPrice * 0.85m;

–> Uso de tipos explícitos (decimal) melhora leitura em regras financeiras
–>
Sufixo m evita ambiguidade de tipo

2. Funções com responsabilidade única (SRP)
Ruim:

public void ProcessUser(User user)
{
    Validate(user);
    Save(user);
    SendEmail(user);
}

Bom:

public void ValidateUser(User user) { /* ... */ }

public void SaveUser(User user) { /* ... */ }

public void SendWelcomeEmail(User user) { /* ... */ }

–> Cada método expressa claramente sua intenção
–> Facilita testes unitários

3. Evitar comentários desnecessários porque o código já explica o que faz:

// Increment the counter
counter++;

4. Estrutura clara e expressiva:
Ruim:

public void DoStuff(List<User> u)
{
    foreach (var x in u)
    {
        if (x.A)
        {
            // ...
        }
    }
}

Bom:

public void ProcessActiveUsers(List<User> users)
{
    foreach (var user in users)
    {
        if (user.IsActive)
        {
            ProcessUser(user);
        }
    }
}

–> Nome do método já explica o comportamento
–> Propriedade IsActive melhora semântica

5. Evitar “código esperto” (clever code), pode ser aceitável, mas em lógica complexa vira problema:
Ruim:

return x ? y : z;

Pior ainda:

return x && y || z;

Bom:

if (x)
{
    return y;
}

return z;

–> Mais explícito
–> Mais fácil de debugar

O código é uma forma de comunicação entre humanos, o compilador é apenas o intermediário. O código é lido muito mais vezes do que é escrito.