Neste artigo vou mostrar como aplicar boas práticas de programação usando exemplos de código criados sem preocupação alguma em ter um código robusto, fácil de manter e fácil de entender. |
Vamos assim aprender a partir de maus exemplos de códigos a usar as boas práticas de programação.
Ao invés de começar teorizando sobre boas práticas e qualidade de código, o que pode levar a uma discussão acirrada, pois as opiniões são muito divergentes quanto à abordagem que se deve dar ao assunto, eu vou tratar o assunto usando um enfoque mais prático partindo de um código mal escrito e implementando boas práticas para que ao final o resultado esteja melhorado.
Assim, vou tratar com exemplos concretos e mostrando que vale apena escrever um código aderente às boas práticas de programação.
Antes de prosseguir com o artigo tenha em mente que eu vou usar a seguinte abordagem :
- Vou mostrar como usar os
recursos da linguagem C# e padrões de projeto na prática ;
- Vou usar exemplos simplificados para focar somente no assunto proposto;
- A abordagem não pretende ser vista como a única solução mas tem como objetivo
que o código qualidade e seja robusto;
- Para tornar mais simples os exemplos e me ater ao unicamente aos problemas eu
não vou me preocupar com tratamento de erros, realizar log de auditorias. etc.;
- Meu objetivo será mostrar soluções comuns e simples para problemas de
programação que ocorrem no dia a dia;
Recursos usados:
Nota: Baixe e use a versão Community 2015 do VS ela é grátis e é equivalente a versão Professional.
Criando o projeto no VS Community
Abra o VS Community 2015 e clique em New Project;
Selecione a linguagem Other Project Types -> Visual Studio Solutions;
Selecione o template Blank Solution e informe o nome BoasPraticas_CSharp e clique no botão OK;
Será criada uma solução vazia onde iremos incluir nossos projetos.
Criando o projeto exemplo : uma classe que cheira mal
Vamos criar um projeto do tipo Class Library em nossa solução e neste projeto definir a nossa classe de partida.
No menu File clique em Add -> New Project ;
Selecione o template Class Library e informe o nome Projeto_BoasPraticas.CodigoRuim e clique em OK;
Pelo nome deu para perceber que neste projeto teremos uma classe com muitos problemas.
Então veja o código da classe abaixo, e, tente entender qual o propósito dessa classe:
class Class1
{
public decimal Calcular(decimal valor, int tipo, int anos)
{
decimal resultado = 0;
decimal desc = (anos > 5) ? (decimal)5 / 100 : (decimal)anos / 100;
if (tipo == 1)
{
resultado = valor;
}
else if (tipo == 2)
{
resultado = (valor - (0.1m * valor)) - desc * (valor - (0.1m * valor));
}
else if (tipo == 3)
{
resultado = (0.7m * valor) - desc * (0.7m * valor);
}
else if (tipo == 4)
{
resultado = (valor - (0.5m * valor)) - desc * (valor - (0.5m * valor));
}
return resultado;
}
}
|
Esse é um tipo de código que estraga o dia de qualquer bom desenvolvedor.
A primeira vista não dá para perceber qual o papel dessa classe (é que nome hein... Class1).
Podemos supor que ela realiza alguns cálculos que estão relacionados a descontos e envolvem valores e tipos e anos.
Vamos assumir o risco e supor que o propósito da classe seja gerenciar o desconto de clientes que realizam compras. E é realmente isso que ela faz.
Eu nem precisaria dizer, mas esta classe esta cheirando mal, é ilegível, difícil de manter, difícil de estender e esta usando más práticas e antipadrões.
Vamos perder um tempo para mostrar os problemas encontrados nesta classe...
Identificando os problemas
1- O problema da nomenclatura (ou falta dela)
Podemos apenas tentar adivinhar o que o método Calcular faz e o quais as funções dos parâmetros usados no método.
É muito difícil extrair um algoritmo de calculo desta classe.
Se você precisar extrair o detalhes do algoritmo usado neste código vai ter que modificar o código ou vai ficar perdendo tempo tentando entender o que o método Calcular faz.
Se após todo esse esforço não criarmos uma documentação sobre isso, ou se ainda não refatorarmos o código todo esse processo vai se repetir quando outro desenvolvedor se deparar com essa classe.
Estamos assim perdendo um precioso tempo...
2- O problema dos números mágicos
Analisando o código você sabe o que significa a variável tipo ? E a variável desc ?
Vou ter que dizer porque acho que você nunca vai descobrir...
A variável tipo indica o status da conta do cliente e a variável desc representa o percentual de desconto que deverá ser usado.
Agora perceba que temos uma instrução if-else if que escolhe como calcular o preço do produto aplicando o desconto.
Em cada instrução if temos a variável tipo comparada com números mágicos que significam alguma coisa; mas significam o quê ?
Você faz alguma ideia que tipo de conta seja a conta 1, 2, 3 e 4 ?
Realmente fica difícil descobrir !!!
Esses números estão relacionados com os tipos de clientes que poderemos ter em relação a sua fidelidade : clientes registrados, clientes comuns, clientes especiais, etc.
3- O problema dos bugs ocultos (difíceis de perceber)
Com um código tão sujo e ilegível é muito fácil não perceber problemas que vão causar bugs e que estão ocultos.
Imagine que precisamos adicionar um novo status de conta de cliente ao nosso sistema, algo do tipo : cliente VIP.
Como esse tipo de status de cliente não esta previsto o bloco if-else if vai retornar o valor 0 pois nenhuma condição será satisfeita. Ou seja o cliente esta comprando mas não esta pagando.
Percebeu o bug ?
Como o problema não é facilmente percebido, existe uma grande chance dele se manifestar quando a aplicação estiver em produção, dando assim prejuízo para sua empresa.
É isso que faz um código não documentado e ilegível , você gasta muito tempo para entender o código e corre riscos de cometer erros difíceis de detectar.
4- O problema dos números mágicos novamente
Estamos à volta novamente com os números mágicos.
Você sabe o que significa os números 0.1, 0.7 e 0.5 ?
Vamos imaginar que você tem que alterar a seguinte linha de código :
resultado = (valor - (0.5m * valor)) - desc * (valor - (0.5m * valor));
Sem saber o que significam os números é um tiro do escuro...
O mesmo problema ocorre no trecho de código a seguir :
decimal desc = (anos > 5) ? (decimal)5 / 100 : (decimal)anos / 100;
Esta linha de código esta calculando o desconto percentual com base no tempo de conta do cliente.
Você conseguiria descobrir isso rapidamente sem ajuda ?
Outro detalhe, o que significa o número 5 em (anos > 5) ? Porque isso esta sendo feito ?
Acredite se quiser mas esse número significa o desconto máximo percentual a qual o cliente pode ter conforme a sua fidelidade.
Fala sério...
5- O problema da duplicação de código (princípio DRY)
Dá para perceber, após algum tempo, que o método Calcular apresenta código repetido em muitos lugares.
O código a seguir :
resultado = (valor - (0.1m * valor)) - desc * (valor - (0.1m * valor));
possui a mesma lógica que a linha de código :
resultado = (valor - (0.5m * valor)) - desc * (valor - (0.5m * valor));
Podemos parametrizar facilmente o código usado e evitar a sua duplicação.
Código
duplicado e espalhado significa maior propensão a erros, e, mais dificuldade de
manter o código.
6- O problema das múltiplas responsabilidades do código (princípio SRP)
Podemos identificar pelo menos 3 responsabilidades em nosso método Calcular:
Isso viola o princípio SRP - Single Responsability Principle - ou princípio da responsabilidade única que diz que uma classe deve ter apenas um motivo para mudar.
E qual o problema disso ?
Se precisarmos modificar uma dessas responsabilidades assumidas pelo método as demais serão afetadas e teremos que testar toda a nossa classe novamente.
Pura perda de tempo.
Tratando de corrigir os problemas
Identificamos os principais problemas descritos acima que se constituem em más práticas e fazem com que o código 'cheire mal' causando problemas e prejuízo.
Vamos agora arregaçar as mangas e corrigir os problemas usando boas práticas para obter um código legível, limpo, fácil de manter e testar.
Faremos isso em etapas para que o entendimento seja facilitado na próxima parte do artigo.
Porque toda a carne
é como a erva, e toda a glória do homem como a flor da erva. Secou-se a erva, e
caiu a sua flor;
Mas a palavra do Senhor permanece para sempre.E esta é a palavra que entre vós
foi evangelizada.
1 Pedro 1:24-25
Veja os
Destaques e novidades do SUPER DVD Visual Basic
(sempre atualizado) : clique e confira !
Quer migrar para o VB .NET ?
Quer aprender C# ??
Quer aprender os conceitos da Programação Orientada a objetos ? Quer aprender o gerar relatórios com o ReportViewer no VS 2013 ? |
Referências:
Super DVD Vídeo Aulas - Vídeo Aula sobre VB .NET, ASP .NET e C#
Super DVD C# - Recursos de aprendizagens e vídeo aulas para C#
Curso Fundamentos da Programação Orientada a Objetos com VB .NET