1. Introdução
"Código limpo" não é nenhum bicho de sete cabeças, é uma ferramenta real de sobrevivência pra quem programa. Em qualquer projeto OOP, mesmo o mais bonito, rapidinho aparecem um monte de classes, campos, métodos, ligações malucas... Se você bagunçar a estética e a estrutura, em uma semana seu próprio código vira um quebra-cabeça impossível. Quer saber mais sobre essa "luta pela sobrevivência"? Dá uma olhada no Robert Martin, "Código Limpo" — é sobre essas batalhas mesmo.
Estilo no código não é "cada um faz do seu jeito", é pra todo mundo viver melhor:
- Seu colega (ou você mesmo) entende rapidinho o que tá rolando.
- Erros (principalmente de arquitetura) aparecem na hora.
- Fica mais fácil de mexer no código, errando menos.
Bora ver como deixar o código OOP daquele jeito que todo mundo gosta: quem revisa, quem trabalha junto e até os linters.
2. Nomes: sua primeira linha de defesa
Nomeando classes
Classes em C# normalmente usam PascalCase (cada parte do nome começa com maiúscula, tipo: MinhaNovaClasse) e o nome tem que responder claramente "O que é isso?". Os nomes devem ser substantivos!
public class ContaDoAluno { /* ... */ }
public class GeradorDeFatura { /* ... */ }
Ruim:
class fazMagica { ... } // Ruim: Que mágica é essa? PascalCase errado.
Nomeando métodos
Métodos — também em PascalCase, mas aqui é melhor usar verbo + objeto da ação:
public void ImprimirRelatorio() { ... }
public string ObterNomeFormatado() { ... }
Métodos têm que mostrar a ação (Imprimir, Obter, Salvar, Calcular etc.), pra quem lê já sacar o que vai acontecer.
Nomeando campos e propriedades
Campos normalmente são private, nomeados com letra minúscula em camelCase, muitas vezes com underline:
private int _quantidade;
private Aluno _dono;
Propriedades — PascalCase, porque fazem parte da interface pública da classe:
public int Saldo { get; set; }
Variáveis
Variáveis locais — camelCase, o mais curto e claro pro contexto:
string nomeEntrada;
int quantidadeAlunos;
E, por favor, variáveis tipo a1, resultado2, algumaCoisa — só se você quiser criar um desafio pra você mesmo no mês que vem.
3. Organização da estrutura da classe
Colocar os membros da classe na ordem certa deixa tudo mais fácil de navegar e entender o que vem depois do quê.
Normalmente fica assim:
- Construtores
- Propriedades
- Métodos
- Tipos aninhados (enum, class etc.)
Exemplo:
public class Aluno
{
// --- Campos ---
private string _nome;
// --- Construtor ---
public Aluno(string nome)
{
_nome = nome;
}
// --- Propriedades ---
public string Nome
{
get => _nome;
set => _nome = value;
}
// --- Métodos ---
public void ImprimirInfo()
{
Console.WriteLine($"Nome: {_nome}");
}
}
Esses "blocos" ficam bem separados por comentários (// --- Métodos ---), principalmente em classes grandes. JetBrains Rider, Visual Studio e outras IDEs deixam você recolher/expandir as seções rapidinho.
4. Comentários e documentação
Comentários são bons. Mas é ruim exagerar ou escrever "explicação pra código confuso", quando dava pra só melhorar o código!
Comentário bom — é aquele que explica o "porquê", não o "o quê".
// Usamos Guid como identificador único porque o sistema é distribuído
public Guid Id { get; set; }
Documentação de métodos, classes e propriedades
Use documentação xml pra classes e métodos públicos. A IDE mostra essas descrições quando você passa o mouse.
/// <summary>
/// Representa um aluno da universidade.
/// </summary>
public class Aluno
{
/// <summary>
/// Nome do aluno.
/// </summary>
public string Nome { get; set; }
}
O que NÃO comentar
- Coisas óbvias (i++ // incrementa i em 1).
- Variáveis mal nomeadas ("// algo acontece aqui" — tá, mas o quê?).
5. Separe para conquistar
Classes e métodos pequenos
Regra de ouro: uma classe — uma responsabilidade (veja Princípio da Responsabilidade Única). Se a classe Aluno cuida de notas, e-mail e agenda — tem algo errado aí.
- Classes até 300-400 linhas — beleza. Mais que isso — já é bom repensar.
- Métodos até 15-20 linhas — fica legível. Tem exceção, tipo método que trata um caso grandão.
Exemplo de método "inchado":
public void Processar()
{
// Notifica o cliente
// Salva alterações
// Envia e-mail
// Escreve logs
// ... (15 passos)
}
Melhor:
public void Processar()
{
NotificarCliente();
SalvarAlteracoes();
EnviarEmail();
RegistrarAtividade();
}
Cada passo virou um método privado separado, o código fica mais compacto e fácil de testar.
6. Dicas úteis
Estrutura visual: formatação, indentação, linhas em branco
A IDE formata o código bonitinho pra você (Ctrl+K, D no Visual Studio, Ctrl+Alt+L no Rider), mas é bom saber os princípios.
- INDENTAÇÃO — 4 espaços. Nada de tab, nem 2 espaços.
- LINHAS EM BRANCO — separe métodos, campos, propriedades.
- CHAVES sempre na linha de baixo pra classes e métodos (estilo Allman):
public class Teste
{
public void Imprimir()
{
Console.WriteLine("Olá");
}
}
"Fortes" e "fracos" membros da classe: modificadores de acesso
Sempre tente deixar tudo o mais fechado possível: só abra o que realmente precisa ser acessado de fora. Se o campo ou método é só pra dentro da classe — deixa private. Só se for pra herança — protected. public — só pra contratos.
Ruim:
public string StringDeConexao; // Qualquer um pode mudar!
Melhor:
private string _stringDeConexao;
public string StringDeConexao
{
get => _stringDeConexao;
private set => _stringDeConexao = value;
}
Usando propriedades automáticas
Com propriedades automáticas e init-only setters, escrever "propriedades manuais" ficou coisa do passado.
Exemplo:
public string Nome { get; set; } // Show!
public int Idade { get; init; } // Só pra inicialização, mais seguro.
Se precisar de propriedades calculadas:
public string NomeCompleto => $"{PrimeiroNome} {UltimoNome}";
Encapsulamento e getters/setters
Se a propriedade tem alguma lógica de negócio pra mudar ou controlar, use campo privado + getter/setter público com lógica.
private int _nota;
public int Nota
{
get => _nota;
set
{
if (value < 0) _nota = 0;
else if (value > 100) _nota = 100;
else _nota = value;
}
}
Assim você não deixa ninguém (nem você mesmo) "quebrar" o objeto sem querer.
7. Mais dicas úteis
Não tenha medo de interfaces e abstrações
Interfaces servem pra contratos legais, testes e expandir o app.
Ruim:
- interface com um método só, que ninguém usa;
- interface que só uma classe implementa.
- interface usada por 2+ classes;
- interface pra abstrair sistemas externos (tipo logging, storage).
Escreva código fácil de testar
Um sinal de código OOP bom é ser fácil de testar.
- Não faça métodos que dependem de variáveis globais ou campos estáticos.
- Não tenha medo de injeção de dependência — via parâmetros do construtor (Dependency Injection).
- Separe lógica (cálculos) e interação com usuário (entrada/saída). Isso facilita não só testar, mas também melhorar o app depois.
Lifehacks e anti-padrões pra iniciantes
- Não escreva "classe Deus" (God Object) que faz tudo.
- Não use "números mágicos" sem explicação (if (status == 42) — por que 42?).
- Não exagere na herança só por herdar — às vezes composição é melhor (classe com campos de outras classes, não herdeira).
- Não escreva métodos gigantes de 100 linhas — ninguém testa nem entende.
- Sempre deixe espaço pra expandir (open/closed principle).
8. Como é um código ruim e um código bom
Exemplo ruim:
class a // Ruim: nome da classe com minúscula.
{
public int b; // não faz sentido, nome ruim
public void c() // Ruim: método com nome de uma letra só.
{
Console.WriteLine(b);
// Ruim: não dá pra saber o que o método faz.
}
}
Exemplo bom:
// Representa um aluno.
public class Aluno
{
// Idade do aluno.
private int _idade;
public int Idade
{
get => _idade;
set => _idade = value < 0 ? 0 : value;
}
// Mostra informações do aluno.
public void ImprimirInfo()
{
Console.WriteLine($"Idade do aluno: {Idade}");
}
}
GO TO FULL VERSION