Domine a Arte do Código: Sugestões e Dicas para Escrever um Bom Código
- Fernando Coregio
- 13 de jun. de 2023
- 13 min de leitura
Atualizado: 14 de jun. de 2023

Nem todos podem escrever um bom código de imediato. Mesmo com alguns meses de experiência em programação, é possível criar aplicações funcionais. No entanto, a escrita de um código de qualidade vai além do simples fato de fazer a aplicação funcionar. Muitos programadores estão satisfeitos em ter um código funcional, mas isso nem sempre significa que seja um bom código. A escrita de um bom código é uma habilidade que demanda esforço e dedicação. É uma verdadeira arte que requer aprendizado constante e prática contínua.
A definição de bom código pode variar de pessoa para pessoa. Na minha concepção, um bom código deve ser confiável, sustentável e eficiente. Muitos desenvolvedores tendem a priorizar o desempenho em detrimento da confiabilidade e da facilidade de manutenção. No entanto, considerando o retorno do investimento a longo prazo (Return On Investment - ROI), a confiabilidade e a facilidade de manutenção são mais importantes do que a eficiência e o desempenho. Se o seu código não é confiável e de fácil manutenção, você e sua empresa acabarão perdendo muito tempo na identificação de problemas e na compreensão do código ao longo da vida útil da aplicação.
Existem vários fatores que contribuem para escrever um bom código e, consequentemente, desenvolver aplicativos confiáveis e de fácil manutenção. Neste artigo, abordaremos alguns desses fatores. Começaremos pela importância da padronização...
Por que é importante padronizar a escrita do código?
A padronização da escrita do código traz uma série de benefícios para os desenvolvedores e equipes de programação. As convenções de nomenclatura, padrões de codificação e melhores práticas descritas neste documento são baseados na minha própria experiência, além de referências e orientações da Microsoft e outras fontes confiáveis.
Embora não exista uma norma padrão que deva ser obrigatoriamente seguida na padronização do código, é importante ressaltar que existem várias normas, e nenhuma delas está completamente errada ou certa. No entanto, seguir alguma regra é melhor do que não seguir nenhuma. O importante é adotar uma abordagem e segui-la de forma consistente.
Quando se trata de uma equipe de desenvolvedores trabalhando no mesmo projeto, a padronização se torna ainda mais desafiadora. Cada membro da equipe pode ter habilidades e preferências diferentes, o que dificulta alcançar uma padronização efetiva. É necessário investir tempo e esforço para convencer todos a adotarem os mesmos padrões.
Nesse contexto, uma abordagem adequada seria estabelecer um documento padrão por meio de consenso comum e utilizá-lo como um modelo a ser seguido pela equipe. Após o início dos trabalhos, o código seria revisado periodicamente para verificar se todos estão aderindo às regras definidas.
A padronização da escrita do código traz uma série de vantagens. Ela promove a legibilidade, facilita a compreensão e manutenção do código, além de melhorar a colaboração entre os membros da equipe. Ao adotar uma abordagem padronizada, você estará criando um ambiente propício para a produção de um código consistente, de qualidade e de fácil manutenção.
Convenções de nomenclatura
Veremos a seguir algumas convenções de nomenclaturas usadas. O objetivo não é definir uma delas mas mostrar o que já foi e esta sendo usado e indicar a mais adequada.
Notação Húngara
A Notação húngara, criada por Charles Simonyi, visa facilitar o reconhecimento do tipo de variável num programa. O nome foi dado a partir de uma brincadeira comum entre os primeiros a conhecer a notação que a achavam estranha, fazendo o seguinte comentário: "É tão estranho que até parece húngaro".(wikipéida : http://pt.wikipedia.org/wiki/Nota%C3%A7%C3%A3o_h%C3%BAngara )
Tipos de indicadores usados pela notação húngara:
Nome | Descrição |
s | String |
sz | Aponta o primeiro caracter da terminação zero da string |
st | Ponteiro da string, o primeiro byte é contado dos caracteres |
h | handle (título) |
msg | Message |
fn | function (usada com pointer) |
c | char (8 bits) |
by | unsigned char (byte or uchar - 8 bits) |
n | Int |
b | Boolean (verdadeiro ou falso) |
f | Flag (boolean, logical) |
u | integer |
w | Word |
ch | Char, com texto ASCII |
l | long int (32 bits) |
dw | unsigned long int (dword - 32 bits) |
A notação húngara era muito usada na linguagem Visual Basic mas atualmente não se recomenda usar este padrão.
camelCase: um padrão de escrita para nomes compostos
camelCase é um termo em inglês utilizado para descrever a prática de escrever palavras compostas ou frases sem espaços entre elas, onde a primeira letra da primeira palavra é iniciada com minúscula e as palavras subsequentes têm suas primeiras letras iniciadas com maiúsculas. Esse padrão é amplamente utilizado em diversas linguagens de programação, como Java, Ruby, PHP e Python, especialmente na definição de classes e objetos.
A adoção do CamelCase traz uma série de benefícios para a legibilidade e clareza do código. Ao utilizar esse padrão, é possível tornar o nome das variáveis, métodos e classes mais concisos e compreensíveis, facilitando a leitura e entendimento do código fonte. Além disso, o uso consistente do CamelCase contribui para a padronização e coesão do código em um projeto.
Exemplos de nomes de variáveis e identificadores seguindo o padrão CamelCase são "valorDoDesconto", "nomeCompleto" e "valorDoImpostoSobreServico". Ao adotar essa convenção de nomenclatura, você estará seguindo uma prática amplamente reconhecida e promovendo a consistência no código, tornando-o mais legível e profissional.
É importante mencionar que cada linguagem de programação pode ter suas próprias convenções de nomenclatura, inclusive para o uso do CamelCase. Por isso, é recomendado consultar as diretrizes de estilo da linguagem em que você está trabalhando para garantir a aderência às melhores práticas específicas.
PascalCase: um padrão de escrita para nomes compostos
PascalCase é um padrão utilizado na escrita de palavras compostas ou frases, onde a primeira letra de cada palavra é iniciada com maiúscula e não há espaços entre elas. Esse padrão é comumente empregado para nomear métodos e classes em diversas linguagens de programação.
Ao utilizar o PascalCase, você consegue tornar os nomes dos métodos e classes mais legíveis e intuitivos. A capitalização inicial de cada palavra facilita a distinção entre os termos e ajuda a identificar as partes que compõem o nome. Além disso, o uso consistente do PascalCase contribui para a padronização do código em um projeto.
Exemplos de nomes de métodos e identificadores seguindo o padrão PascalCase são "CalculaImpostoDeRenda()" e "ValorDoDesconto". Esses exemplos mostram como o padrão permite que você crie identificadores claros e concisos, transmitindo com facilidade a intenção e a funcionalidade do código.
É importante ressaltar que cada linguagem de programação pode ter suas próprias convenções de nomenclatura, incluindo o uso do PascalCase. Por isso, é recomendado consultar as diretrizes de estilo da linguagem em que você está trabalhando para garantir a aderência às melhores práticas específicas.
Usando CamelCase e PascalCase: Uma combinação comum
É comum observar que a maioria dos desenvolvedores que trabalham com as linguagens C# e VB .NET utilizam uma combinação de CamelCase e PascalCase em suas práticas de nomenclatura.
Aqui estão alguns exemplos de como esses padrões são aplicados:
Classes: São nomeadas usando PascalCase, como "PessoaJuridica".
Interfaces: Recebem um "I" inicial seguido por PascalCase, como "ICliente".
Métodos públicos e propriedades: São nomeados usando PascalCase, como "NomeCompleto()".
Métodos privados: Utilizam CamelCase, como "calculaDesconto()".
Variáveis públicas: São nomeadas usando PascalCase, como "SobreNome".
Variáveis privadas: Utilizam CamelCase, como "impostoPredial".
Constantes: São escritas em maiúsculas com sublinhado, como "VALOR_DESCONTO".
Esses padrões ajudam a manter uma consistência na nomenclatura do código, facilitando a legibilidade e a compreensão. Ao seguir essas convenções, torna-se mais fácil para outros desenvolvedores entenderem e trabalharem com seu código.
É importante ressaltar que essas convenções podem variar entre diferentes projetos e linguagens de programação. Portanto, é sempre recomendado verificar e seguir as diretrizes de estilo específicas da linguagem ou do projeto em que você está trabalhando.
Sugestões para escrever um bom código: Padronização e boas práticas
Escrever um código bem estruturado e de fácil compreensão é essencial para o desenvolvimento de software de qualidade. A seguir, apresento algumas sugestões para alcançar esse objetivo, começando pela padronização:
Nomes de Classes: Utilize o padrão PascalCase para nomear classes, onde a primeira letra de cada palavra é iniciada com maiúscula. Por exemplo, "Cliente", "Pedido", "Produto".
Nomes de Métodos: Também utilize o padrão PascalCase para nomear métodos, seguindo a mesma convenção das classes. Por exemplo, "CalcularImposto", "ObterDadosCliente".
Nomes de Variáveis e Parâmetros de Métodos: Utilize o padrão CamelCase, iniciando com letra minúscula para nomear variáveis e parâmetros de métodos. Por exemplo, "totalContador", "nomeCompleto".
csharp
int totalContador = 0;
void ExibirMensagem(string nome)
{
string mensagemCompleta = "Olá " + nome;
}
Nomes de Interfaces: Utilize o prefixo 'I' seguido do padrão CamelCase para nomear interfaces. Por exemplo, "IEntidade", "IService".
Evite a Notação Húngara: Não utilize a notação húngara para nomear variáveis, onde o tipo é incluído no nome. Prefira utilizar nomes descritivos que reflitam o propósito da variável.
Nomes Significativos: Utilize nomes significativos e descritivos para nomear variáveis. Evite abreviações e garanta que o nome escolhido represente claramente o propósito da variável.
Evite Nomes de Variáveis Genéricos: Evite utilizar nomes de variáveis com um único caractere, como 'i', 'n', 'c', 's', 't', a menos que seja para contadores em laços de repetição. Prefira utilizar nomes mais descritivos, como 'índice', 'temporário', 'contador', entre outros.
Não Utilize Sublinhado para Variáveis Locais: Evite utilizar sublinhado como prefixo para variáveis locais. Por exemplo, "_email" não é uma boa prática.
Evite Nomes de Variáveis que são Palavras-Chave: Evite utilizar nomes de variáveis que sejam palavras-chave na linguagem de programação utilizada.
Prefixos em Elementos de Interface: Utilize os prefixos apropriados para cada elemento de interface utilizado. Por exemplo, "txtNome" para uma caixa de texto, "btnEnviar" para um botão.
Seguir essas sugestões de padronização e boas práticas de nomenclatura contribui para a legibilidade e manutenibilidade do código, facilitando o entendimento e a colaboração entre os desenvolvedores. Lembre-se de sempre verificar e adotar as diretrizes de estilo específicas da linguagem ou projeto em que está trabalhando.
Indentação e espaçamento
Para tornar o código mais legível e facilitar a compreensão, é importante adotar boas práticas de indentação e espaçamento. A seguir, apresento sugestões para melhorar esses aspectos:
Indentação com TAB: Utilize a tecla TAB para realizar a indentação do código, não use espaços. É recomendado configurar o tamanho do TAB como igual a 4 espaços.
Comentários alinhados: Os comentários devem estar no mesmo nível de recuo do código correspondente.
Exemplo:
csharp code
// Formato de uma mensagem e exibição
string mensagemCompleta = "Olá" + nome;
DateTime dataAtual = DateTime.Now;
Chaves no mesmo nível: No caso da linguagem C#, as chaves { } devem estar no mesmo nível de recuo do código fora das chaves.
Exemplo:
csharp code
if(string.IsNullOrEmpty(nome))
{
Console.Write("Mensagem");
Console.WriteLine("\n");
Console.ReadLine();
}
Linhas em branco para separar grupos lógicos de código: Utilize uma linha em branco para separar grupos lógicos de código, melhorando a legibilidade.
Exemplo:
csharp code
bool Aviso(string nome)
{
string mensagemCompleta = "Olá " + nome;
DateTime dataAtual = DateTime.Now;
string mensagem = mensagemCompleta + ", a hora é: " +
dataAtual.ToShortTimeString();
MessageBox.Show(mensagem);
if (...)
{
// faça algo// ...return false;
}
return true;
}
bool Aviso(string nome)
{
string mensagemCompleta = "Olá " + nome;
DateTime dataAtual = DateTime.Now;
string mensagem = mensagemCompleta + ", a hora é: " +
dataAtual.ToShortTimeString();
MessageBox.Show(mensagem);
if (...)
{
// faça algo// ...return false;
}
return true;
}
Espaços ao redor dos operadores e colchetes: Utilize um único espaço antes e depois de cada operador e colchete.
Exemplo:
csharp code
if (exibeValor == true)
{
for (int i = 0; i < 10; i++)
{
//
}
}
Essas sugestões ajudam a melhorar a legibilidade e a manutenibilidade do código, tornando-o mais claro e de fácil compreensão para você e outros desenvolvedores que possam interagir com o código.
Boas práticas de programação
Evite métodos muito longos: É recomendado que um método não tenha mais do que 30 linhas de código. Caso um método esteja muito extenso, considere fazer uma refatoração.
Nomes de métodos descritivos: O nome de um método deve refletir claramente sua funcionalidade. Se o nome do método for autoexplicativo, não é necessário adicionar documentação explicando sua função.
Bom:
csharp code
void CalculaValorImposto(int salario)
{
// calcula imposto
}
Ruim:
// Este método calcula o valor do imposto
void Calcular(int salario)
{
// calcula imposto
}
Métodos com uma única tarefa: Um método deve ter uma única responsabilidade e não deve combinar mais de uma tarefa, mesmo que sejam simples. Isso segue o princípio da Responsabilidade Única (SRP).
Bom:
csharpCopy code
void CalculaValorImposto(int salario)
{
// calcula impostodouble imposto = salario * 0.25;
}
Ruim:
void Calcular(int salario)
{
// calcula impostodouble imposto = salario * 0.25;
// envia um email informando o cliente
EnviaEmail();
}
Tratamento de valores inesperados: Ao lidar com parâmetros que podem ter dois valores possíveis, evite assumir que a única possibilidade é o valor oposto ao escolhido. Trate casos inesperados adequadamente para facilitar a detecção de erros.
Bom:
csharp code
if (tipoMembro == TipoMembro.Registrado)
{
// Registrado
}
else if (tipoMembro == TipoMembro.Convidado)
{
// Convidado
}
else
{
// Tipo inesperado lança uma exceção // (Se um novo tipo for
introduzido, podemos encontrar o problema com facilidade)
throw new Exception("Tipo de membro inesperado: " +
tipoMembro.ToString() + ".");
}
Utilização de constantes: Evite definir números fixos diretamente no código. Em vez disso, utilize constantes declaradas no início do arquivo para atribuir valores. Isso torna o código mais legível e facilita a manutenção.
Bom:
csharpCopy code
const int meses = 12;
const int semanas = 52;
const int dias = 365;
const double diasPorSemana = (double)dias / (double)semanas;
const double diasPorMes = (double)dias / (double)meses;
Comparação de strings com conversão de caso: Ao fazer comparações de strings, converta as strings para minúsculas ou maiúsculas antes de comparar. Isso garante que a comparação seja realizada corretamente, mesmo que as strings estejam escritas de forma diferente em relação ao caso.
Bom:
csharp code
if (nome.ToLower() == "coregio")
{
// ...
}
Ruim:
if (nome == "coregio")
{
// ...
}
Uso de String.Empty: Utilize String.Empty em vez de "" para representar uma string vazia. Isso torna o código mais claro e legível.
Bom:
csharp code
if (nome == String.Empty)
{
// ...
}
Ruim:
if (nome == "")
{
// ...
}
Evite variáveis membros públicas ou protegidas: Em vez disso, mantenha as variáveis como privadas e exponha propriedades públicas ou protegidas para acessá-las. Isso ajuda a manter o encapsulamento e facilita o rastreamento de alterações nas variáveis.
Utilize enum quando apropriado: Em vez de utilizar números ou strings para representar valores discretos, utilize enumerações (enums). Isso torna o código mais legível e ajuda a evitar erros de digitação.
Bom:
csharp code
enum TipoEmail
{
Html,
PlainText,
Attachment
}
void EnviaEmail(string mensagem, TipoEmail tipoDeEmail)
{
switch (tipoDeEmail)
{
case TipoEmail.Html:
// manda email em HTML
break;
case TipoEmail.PlainText:
// manda email em texto simples
break;
case TipoEmail.Attachment:
// manda email com anexo
break;
default:
// manda email padrão
break;
}
}
Tratamento adequado de exceções: Capture apenas a exceção específica que você deseja tratar, em vez de capturar uma exceção genérica. Isso permite um tratamento mais adequado e ajuda na identificação de problemas.
Relançamento de exceções: Ao relançar uma exceção, utilize a instrução throw sem especificar a exceção original. Isso preserva a pilha de exceções original.
Blocos try-catch específicos: Evite escrever blocos try-catch muito grandes. Se necessário, utilize um bloco try-catch separado para cada tarefa que você executa e coloque apenas a parte específica do código dentro do try-catch. Isso facilita a identificação da parte do código que gera a exceção e permite fornecer mensagens de erro específicas ao usuário.
Criação de exceções personalizadas: Se necessário, crie suas próprias classes de exceção personalizadas em sua aplicação. Evite herdar diretamente da classe base SystemException e prefira herdar de ApplicationException.
Essas são algumas boas práticas de programação que podem ser seguidas para escrever um código mais limpo, legível e de fácil manutenção.
Arquitetura em camadas:
É recomendado sempre utilizar uma arquitetura em camadas ao desenvolver um software. Isso envolve separar as responsabilidades em diferentes camadas, como a camada de apresentação, camada de lógica de negócios e camada de acesso a dados. Essa abordagem melhora a modularidade, facilita a manutenção e permite a reutilização de código.
Camada de acesso a dados: Evite acessar diretamente o banco de dados a partir das páginas da interface do usuário. Em vez disso, crie uma camada de acesso a dados dedicada que execute todas as tarefas relacionadas ao banco de dados. Isso proporciona maior flexibilidade, permitindo que você altere o banco de dados subjacente com mais facilidade, sem impactar diretamente a interface do usuário.
Tratamento de exceções no acesso a dados: Na camada de acesso a dados, utilize blocos try-catch para capturar exceções relacionadas ao banco de dados. É importante registrar essas exceções, incluindo informações relevantes como o comando executado, o nome do procedimento armazenado, os parâmetros e a string de conexão utilizada. Após o registro, a exceção pode ser lançada para ser tratada por outra camada da aplicação, que tomará as medidas adequadas.
Separação em assemblies: Uma prática recomendada é dividir a aplicação em várias assemblies (bibliotecas de classes). Por exemplo, agrupe classes de utilitários independentes em uma biblioteca de classes separada e coloque os arquivos relacionados ao banco de dados em outra biblioteca de classes. Essa separação ajuda a organizar e modularizar o código, facilitando a manutenção e promovendo a reutilização.
Essas são algumas diretrizes de arquitetura que podem contribuir para o desenvolvimento de um software mais estruturado, modular e de fácil manutenção. É importante adaptar essas práticas de acordo com as necessidades específicas do projeto e seguir outros princípios de arquitetura, como o princípio de responsabilidade única e a separação de preocupações.
ASP .NET
Gerenciamento de variáveis de sessão: Evite o uso indiscriminado de variáveis de sessão em todo o código. Em vez disso, crie classes dedicadas que encapsulem o acesso às variáveis de sessão e exponham métodos para recuperar e definir os valores armazenados. Essas classes podem usar a propriedade System.Web.HttpContext.Current.Session para acessar a sessão de forma segura.
Limite o armazenamento de objetos grandes na sessão: Evite armazenar objetos grandes na sessão, pois isso pode consumir uma quantidade significativa de memória do servidor, especialmente quando há muitos usuários acessando o sistema. Avalie se é realmente necessário armazenar objetos grandes na sessão ou se é possível utilizar estratégias alternativas, como o uso de bancos de dados ou caches.
Utilização de folhas de estilo (CSS): É recomendado sempre utilizar folhas de estilo (CSS) para controlar a aparência das páginas em vez de especificar estilos diretamente nas páginas. Evite definir o nome e tamanho da fonte diretamente nas páginas e utilize classes de estilo apropriadas. Essa prática torna mais fácil modificar a interface do usuário no futuro, pois basta atualizar as folhas de estilo em vez de modificar cada página individualmente. Além disso, se desejar oferecer personalização da interface para diferentes clientes, basta criar folhas de estilo adicionais para cada um deles.
Essas orientações ajudam a promover boas práticas no desenvolvimento de aplicações ASP.NET, como o uso adequado das variáveis de sessão, o gerenciamento eficiente de recursos e a separação de estilos e conteúdo. Lembre-se também de considerar outros aspectos importantes, como a performance, segurança e acessibilidade ao projetar e desenvolver suas aplicações ASP.NET.
Comentários
Evite comentários excessivos: Evite escrever comentários para cada linha de código ou variável declarada. Comentários devem ser usados com moderação e apenas quando necessário para explicar conceitos complexos, fornecer contexto adicional ou esclarecer partes obscuras do código. Um código bem escrito, com nomes de variáveis e métodos significativos, geralmente é autoexplicativo e requer menos comentários.
Use comentários de forma adequada: Utilize a sintaxe correta para comentários. Prefira o uso de // para comentários de linha única ou /// para comentários de documentação XML (quando aplicável). Evite o uso de /* ... */ para comentários de várias linhas, a menos que seja estritamente necessário.
Código legível reduz a necessidade de comentários: Escreva código legível, com nomes claros e significativos para variáveis e métodos. Um código bem estruturado e autoexplicativo diminui a necessidade de comentários adicionais. Priorize a clareza e simplicidade do código, tornando-o mais fácil de entender para os outros desenvolvedores.
Comentários desnecessários podem causar confusão: Evite comentar o óbvio ou escrever comentários desnecessários para partes de código que são facilmente compreensíveis. Comentários desatualizados ou que não correspondem ao código atual podem levar a confusões e erros. Mantenha os comentários alinhados com o código e remova ou atualize-os conforme necessário.
Documente lógica complexa ou incomum: Se você precisar utilizar lógica complexa ou incomum em seu código, é importante documentá-la adequadamente. Explique o raciocínio por trás da abordagem escolhida e forneça comentários suficientes para ajudar os outros desenvolvedores a entenderem a lógica envolvida.
Explique escolhas de valores especiais: Se você inicializar uma variável numérica com um valor especial que difere do padrão (como 0 ou -1), documente a razão por trás dessa escolha incomum. Isso ajuda a evitar confusões e facilita a manutenção do código no futuro.
Verifique a correção gramatical e ortográfica: Ao escrever comentários, verifique a correção gramatical e ortográfica. Comentários com erros de ortografia ou gramática podem dificultar a compreensão e transmitir uma impressão negativa sobre a qualidade do código. Utilize ferramentas de verificação ortográfica para garantir a precisão dos seus comentários.
Seguindo essas práticas, você poderá utilizar comentários de forma eficaz para melhorar a compreensão do código, fornecer explicações necessárias e facilitar a colaboração entre os desenvolvedores. Lembre-se de que o código bem escrito e autoexplicativo é sempre preferível a comentários excessivos.
"Porque Deus amou o mundo de tal maneira que deu o seu Filho unigênito, para que todo aquele que nele crê não pereça, mas tenha a vida eterna." - João 3:16 (Bíblia Sagrada, Almeida Corrigida e Revisada Fiel)
Comments