8
1 Boas práticas de programação A vida de um programador não é fácil. A tecnologia é algo que não para de evoluir e a cada dia surge uma forma diferente de escrever um código. A carreira de um profissional de informática é algo de sua responsabilidade. O código produzido por esse profissional também é de sua responsabilidade. Um bom código não é somente aquele que é funcional, mas também aquele que não tem valores exorbitantes para ser mantido. A maior parte dos programadores não gostam de alterar códigos mal escritos. Isso é algo que traz muita frustração e muitas vezes um retrabalho desnecessário. Clean Code Um código limpo deve ser: • Simples: código fácil de entender; • Direto: vai direto ao ponto, não dá “voltas" para atingir seu objetivo; • Eficiente: código que faz o que é proposto; • Sem duplicidade: não faz o que outra parte do código já faz; • Elegante: porque é diferente dos outros códigos; • Feito com cuidado: quem fez teve preocupação em produzir aquele código. Antes de falarmos sobre como fazer para atingir esse nível de qualidade, vamos falar um pouco sobre testes. Importância dos testes

Boas Práticas de Programação

Embed Size (px)

DESCRIPTION

Boas Práticas de Programação

Citation preview

  • 1

    Boas prticas de programao

    A vida de um programador no fcil. A tecnologia algo que no para de evoluir e a cada dia surge uma

    forma diferente de escrever um cdigo. A carreira de um profissional de informtica algo de sua

    responsabilidade.

    O cdigo produzido por esse profissional tambm de sua responsabilidade. Um bom cdigo no somente

    aquele que funcional, mas tambm aquele que no tem valores exorbitantes para ser mantido. A maior

    parte dos programadores no gostam de alterar cdigos mal escritos. Isso algo que traz muita frustrao e

    muitas vezes um retrabalho desnecessrio.

    Clean Code

    Um cdigo limpo deve ser:

    Simples: cdigo fcil de entender;

    Direto: vai direto ao ponto, no d voltas" para atingir seu objetivo;

    Eficiente: cdigo que faz o que proposto;

    Sem duplicidade: no faz o que outra parte do cdigo j faz;

    Elegante: porque diferente dos outros cdigos;

    Feito com cuidado: quem fez teve preocupao em produzir aquele cdigo.

    Antes de falarmos sobre como fazer para atingir esse nvel de qualidade, vamos falar um pouco sobre testes.

    Importncia dos testes

  • 2

    Construir um software no somente escrever cdigo e v-lo funcionar, voc saber que aquele cdigo ser

    manutenvel e que outras pessoas vo alter-lo.

    Para isso, teste fundamental! Voc tem que ser responsvel por aquilo que escreve e saber que seu sistema

    tem que continuar funcionando. Neste contexto, temos a primeira dica sobre um cdigo limpo: "Toda linha

    que voc escrever deve estar testada e ponto final !"

    Muitas empresas veem testes como gastos maiores no projeto, o que de fato acontece, porm a qualidade do

    software produzido algo significante. Quando no se produz teste automatizado, a quantidade de testes

    manuais so maiores e muitas vezes o custo desses testes tambm maior.

    Escrevendo um bom cdigo

    Nomes significativos

    Mtodos, nomes de variveis e etc. devem possuir nomes que significam alguma coisa em relao ao seu

    objetivo. Os nomes utilizados devem responder todas as questes a seguir:

    Porque existem?

    O que fazem?

    Como so usadas?

    Vamos imaginar que um sistema de um motor de um carro tenha um mtodo com o nome de run ao invs

    de acelerar. Se voc pegar um cdigo com esse nome voc ter que estudar todo o mtodo para saber o

    que ele faz.

    Algo muito comum encontrado nos cdigos o tipo de declarao apresentado na Listagem 1.

    Listagem 1. Exemplo de declarao

    public class NotaFiscal {

    private Date d1;//Data da compra

    private Date d2;//Data de vencimento

    private boolean validaDatas(){

    //Valida se data do vencimento maior que a data de compra

    if(d1.after(d2))){

    return true;

    }

    return false;

    }

    //getters e setters

    }

    Se um nome de classe, mtodo ou atributo requer um comentrio, ele no est revelando sua real inteno.

    Quando colocamos uma linha em nosso cdigo com um comentrio ao lado no estamos dando o nome

    correto ao atributo ou mtodo. O cdigo quando bem escrito deve ser algo que seja de fcil leitura, algo que

    uma pessoa leiga conseguiria ao menos saber o que o mesmo faz. Os nomes utilizados devem ser

    pronunciveis, algo que voc entenda.

    Observe no exemplo da Listagem 2 como essa prtica torna o cdigo mais fcil de ser entendido.

  • 3

    Listagem 2. Exemplo de declarao considerando boas prticas

    public class NotaFiscal {

    private Date dataCompra;

    private Date dataVencimento;

    private boolean isDataVencimentoMaiorDataCompra(){

    return dataCompra.after(dataVencimento);

    }

    //getters e setters

    }

    Evite notao hngara

    A notao Hngara visa facilitar o reconhecimento do tipo de varivel em um programa colocando em seu

    nome um sufixo descrevendo seu tipo (ver Listagem 3). Entretanto, com o advento de novas linguagens,

    tcnicas mostradas aqui e testes automatizados, a notao hngara se mostra desnecessria.

    Existe uma certa tendncia para a criao de classes e mtodos menores de modo que as pessoas possam ver

    onde cada varivel que esto usando foi declarada. Alm disso, os testes indicam os tipos e maneiras de

    usar, validando o comportamento esperado do mtodo.

    Listagem 3. Exemplo de uso de notao hngara

    public class Pessoa {

    private String nomeString;

    // No existe aqui a necessidade de se colocar a palavra 'String', pode-se somente

    ficar 'nome'

    //getters e setters

    }

    Classes e mtodos

    Nome de classes devem ser substantivos e no conter verbos. J nomes de mtodos devem conter verbos

    pois eles indicam aes.

    A regra para mtodos : A primeira regra dos mtodos que eles devem ser pequenos. A segunda regra

    que eles devem ser menores ainda.

    Mtodos e classes menores so mais fceis de ler e entender, alm de manter claro. Segundo o livro,

    podemos considerar as seguintes mtricas:

    Mtodos

  • 4

    Mtodos e funes devem fazer somente uma coisa, faz-la certa e somente faz-la.

    Poderamos analisar essa frase como um princpio da coeso no seu cdigo. Muitas vezes no fcil saber

    se aquele mtodo est fazendo somente uma coisa. Uma dica para isso : voc deve tentar extrair parte do

    seu cdigo para um mtodo, se voc conseguir porque aquele seu mtodo realmente no est tendo uma

    funo apenas.

    Imagine que voc tenha um mtodo onde quisssemos mostrar os detalhes de um usurio:

    private void mostrarDadosUsuario(Usuario usuario){

    mostrarCabecalhoUsuario();

    System.out.print(Nome: , usuario.getNome());

    System.out.print(Sobrenome: , usuario.getSobrenome());

    }

    Neste exemplo, as linhas do System.out.print so os detalhes do usurio. Mas ser que isso no ficaria

    melhor escrito se estivesse de acordo com o cdigo da Listagem 4?

    Listagem 4. Separando mtodos

    private void mostrarDadosUsuario(Usuario usuario){

    mostrarCabecalhoUsuario();

    mostrarDetalhesUsuario();

    }

    private void mostrarDetalhesUsuario{

    System.out.print(Nome: , usuario.getNome());

    System.out.print(Sobrenome: , usuario.getSobrenome());

    }

    Se um dia voc quiser apenas listar os dados de um usurio ficar mais fcil. Agora temos os mtodos

    separados. Essa prtica tambm um bom exemplo do tipo de refatorao chamada Extract Method.

    Um outro item que deve ser observado a quantidade de parmetros de um mtodo. Voc deve ter uma

    justificativa muito boa para ter uma quantidade to grande de parmetros em um mtodo.

    Um agravante de um mtodo com vrios parmetros a dificuldade de se testar uma vez que voc dever

    testar todas as combinaes possveis.

    Outra situao a que voc deve estar atento com um mtodo que informa que ir fazer uma determinada

    ao e faz outra. Observe a Listagem 5.

    Listagem 5. Mtodos com objetivos mal definidos

    public boolean verificarSenha(String senha){

    if(senha.equals(zzz)){

    Session.initialize();

    return true;

    }

    return false;

    }

    O objetivo do mtodo verificar a senha, porm, se a senha estiver correta o mesmo inicia uma sesso, ou

    seja, o mtodo j no tem a coeso esperada, pois possui duas responsabilidades.

  • 5

    Uma soluo melhor para esse cenrio pode ser observada na Listagem 6.

    Listagem 6. Ajuste do objetivo do mtodo

    if(verificaSenha(zzz){

    Session.initialize();

    }

    public boolean verificarSenha(String senha){

    if(senha.equals(zzz)){

    return true;

    }

    return false;

    }

    Comentrios nos cdigos

    Comentrios, apesar de importantes, podem trazer desinformao. Por que podemos afirmar isso? Algum

    conhece programadores que atualizam comentrios? H vrios cdigos com vrios comentrios que no

    serviam para nada e, pior, confundiam. Se um mtodo ou uma classe estiver bem escrito, a importncia do

    comentrio minimizada.

    Outro ponto importante, um comentrio no ir esconder um cdigo ruim. Observe o exemplo a seguir:

    Date d1;

    Esse cdigo j est ruim, de nada adianta mudarmos para:

    Date d1; //dia da semana

    Esse comentrio no ir se propagar para todo o cdigo e sempre que voc se deparar com uma linha como

    d1.after(d2);" voc vai continuar no entendendo o propsito do cdigo.

    Podemos tentar colocar uma regra nisso. Muitas vezes quando se comenta um cdigo, pode ser que o mesmo

    precise ser refatorado. Lembra dos exemplos anteriores onde d1 passou a ser dataCompra ? Com essa

    mudana seu cdigo pode ser entendido por todos e se fizermos essa refatorao o cdigo passa a no

    precisar mais de comentrio.

    Observe agora o exemplo a seguir:

    //Verifica se o usurio tem direito ao benefcio

    if(usuario.getIdade() > 10 && usuario.getIdade() < 20){

    .

    }

    Observe agora o exemplo ajustado na Listagem 7.

    Listagem 7. Eliminando o comentrio do cdigo

    if(isUsuarioTemDireitoAoBeneficio(usuario)){

    .

    }

    private boolean isUsuarioTemDireitoAoBeneficio(Usuario usuario){

    if(usuario.getIdade() > 10 && usuario.getIdade() < 20){

    return true;

    }

  • 6

    return false;

    }

    Note que tiramos o comentrio, melhoramos o cdigo e o tornamos mais legvel. Agora a leitura do cdigo

    suficiente para saber o que ele realmente faz.

    Outro tipo de comentrio que deve ser evitado apresentado no exemplo a seguir:

    private boolean isUsuarioTemDireitoAoBeneficio(Usuario usuario){

    if(usuario.getIdade() > 10 && usuario.getIdade() < 20){

    return true; //Retorna verdadeiro

    }

    return false; //Retorna falso

    }

    O return do mtodo lgico, no h necessidade de indicar o que o mesmo est retornando.

    Em relao a comentrios, podemos dizer que: Qualquer comentrio que faa voc olhar para outras

    partes do seu cdigo para entend-lo no valem os bits que consomem.

    Por outro lado, existem momentos em que o comentrio importante. Digamos que voc tenha um trecho

    em seu cdigo que vai demandar um tempo de processamento alto ou a disponibilidade de um recurso.

    Nesses casos, comentrios acabam sendo teis.

    Algumas vezes tambm no se consegue colocar um nome em um mtodo que explique o porqu o

    desenvolvedor tomou aquela deciso.

    Formatao

    Formatao importante, pois se trata de comunicao.

    Temos que considerar que o cdigo a maneira que a equipe de desenvolvimento vai se comunicar. Uma

    pessoa no gostaria de receber uma carta cifrada onde tivesse que interpretar o que est escrito nela,

    podemos pensar assim na hora de escrever um cdigo.

    Outra ponto importante que se voc pega um cdigo bem estruturado, voc vai querer mant-lo bem

    estruturado. ruim para qualquer desenvolvedor ter acesso a um cdigo sem formatao, sem endentao e

    ter que fazer sua leitura como se fosse um texto sem qualquer pontuao.

    Alm disso, mtodos com conceitos relacionados devem ficar verticalmente prximos e a ordem dos

    mtodos deve criar um fluxo de leitura melhorando a legibilidade do cdigo.

    Uma boa endentao fundamental, mas no podemos ter muitos nveis. Observe como o trecho a seguir

    poderia se tornar confuso caso a lgica implementada fosse complexa:

    if(a>1){

    if(b>1){

    if(c>1){

    if(z>1){

    }

    }

    }

    }

  • 7

    Tratamento de erros

    "Quando estamos programando devemos tratar os possveis erros que nossa aplicao poder lanar, as

    coisas podem dar errado e temos que estar certos que nosso cdigo far o que deve fazer."

    Tratamento de erro de responsabilidade do desenvolvedor. preciso garantir que o cdigo vai ter um

    tratamento para cada situao. Prefira lanar uma exception ao invs de retornar um cdigo de erro. Estes

    retornos desorganizam a chamada do mtodo e pode-se facilmente esquecer de verific-los.

    Dentro do seu mtodo voc j pode ver o erro que est sendo retornado e trat-lo ali. Defina o fluxo do

    mtodo separando as regras de negcio de erros ou outras situaes. Para seus erros, crie mensagens

    informativas mencionando a operao que falhou e o tipo de falha.

    Procure utilizar exceptions para situaes inesperadas, por exemplo: seu cdigo est lendo um arquivo e a

    rede se tornou indisponvel.

    TDD

    TDD nada mais que o desenvolvimento guiado por testes. As trs regras do TDD so:

    Voc no pode escrever um cdigo at que tenha criado um teste falhando;

    Voc no pode escrever mais teste do que seja suficiente para falhar;

    Voc no pode escrever mais cdigo do que o suficiente para passar no teste que est falhando.

    Assim, se voc tiver que testar se um CPF vlido, por exemplo, voc deve criar alguns testes tais como:

    se o CPF for em branco;

    se o CPF estiver com menos caracteres.

    Os testes devem considerar as caractersticas F.I.R.S.T:

    *F (Fast): deve ser rpido. Testes demorados tiram a motivao dos profissionais responsveis por sua

    execuo;

    *I (Independent): no podem depender um do outro pois se um falha o outro vai falhar tambm;

    *R (Reapetable): executando mais de uma vez eles devem retornar sempre o mesmo resultado;

    *S (Self-Validating): devem se autovalidar;

    *T (Timely): devem ser feitos antes do cdigo.

  • 8

    Refatorao

    Escrever um bom cdigo muitas vezes pode no parecer uma misso to simples. Considere o trecho de

    cdigo a seguir:

    private boolean isStringVazia(String texto){

    if (!StringUtils.isNullOrEmpty(texto) && !texto.equals("")) {

    //...

    }

    }

    Concorda que o "!texto.equals("")" no serve para nada? Se fizermos a refatorao a seguir obteremos o

    mesmo resultado:

    private boolean isStringVazia(String texto){

    if (!StringUtils.isNullOrEmpty(texto)) {

    //...

    }

    }

    Agora, digamos que ainda assim estivssemos com receio de fazer essa refatorao. Neste caso, a presena

    de um simples teste unitrio poderia eliminar a dvida referente ao fato da funcionalidade continuar

    desempenhando seu papel corretamente.

    A refatorao uma das melhores prticas para melhorarmos nosso cdigo. Seu cdigo pode ser eficaz, ou

    seja, fazer o que se deseja, mas tambm pode ser eficiente, fazer o que se deseja da melhor maneira possvel.