Neste artigo veremos alguns princípios básicos e muito importantes para o desenvolvimento de um bom projeto, código e sistema. É óbvio que existem diversos métodos e características para desenvolver um bom projeto de software, mas focaremos neste artigo em alguns dos mais importantes e muita das vezes ignorados, por pressa, inexperiência ou falta de conhecimento necessário.

Nosso objeto é focar em boas práticas, nada sobre explicação de códigos ou ferramentas. Queremos com este artigo mostrar como aplicar tais características. Mostraremos em Java, mas como já dissemos, o foco não é a técnica e sim o conceito, então você poderá simplesmente aplicar em outra linguagem Orientada a Objetos.

Generalizar para Reutilizar

Nossa primeira característica é a generalização ao máximo do seu código para torná-lo reutilizável, quantas vezes forem necessárias. Generalizar, em outras palavras, é tornar seu sistema poderoso o suficiente para adaptar-se a várias situações, mesmo aquelas que você nem pensou que podem ocorrer.

Vamos pensar no seguinte cenário: você deve desenvolver uma classe chamada 'CaixaSurpresa' que será utilizada em diversos locais do seu sistema. Na verdade, são outros desenvolvedores que irão utilizá-la, mas você é o responsável por criá-la. Nessa Caixa Surpresa pode haver diversos tipos de objetos: bolas, tesouras, papéis e assim por diante. Sua classe deve ter um método para retornar uma lista de objetos de acordo com o que for solicitado.

Então você não sabe quais os objetos podem ser retornados (são inúmeros) e é inviável e impraticável ficar criando um “getObjetoX(), getObjetoY()...”. Nossa solução foi usar a técnica de 'Generics' do Java para solucionar esse problema, mas se você tiver outra ideia que também resolva e torne seu código Genérico o suficiente para resolver tal problema, vá em frente. Observe a Listagem 1.

Listagem 1. Aplicando Cenário da Caixa Surpresa


  import java.util.List;
   /*
   * Temos aqui uma Caixa Surpresa, ou seja, dentro da nossa caixa
   * podem haver os mais diversos tipos de objetos 
   * (bola, papel, tesoura e etc).
   * */
  public class CaixaSurpresa<ObjetoSurpresa> {
         
         //Retorna nossa lista de objetos surpresas
         public List<ObjetoSurpresa> getObjetosSurpresa(){
               
               /*
                * Não mostraremos a implementação desse método, 
                * pois é desnecessário para nosso artigo.
                *
                * Imagine apenas que ele retorna uma lista de objetos 
                 * de acordo com o tipo passado
                * no generics 'ObjetoSurpresa'.
                * */
               List<ObjetoSurpresa> objetos = 
                dao.findTodosObjetosByClass(this);
               
               return objetos;
         }
       
  }
   /*
   * Nossa class comprador é responsável por pegar objetos
   * dentro da classe CaixaSurpresa
   * */
  public class Comprador {
         
         public static void main(String ... args){
               
               //Perceba que estamos procurando quantas 
                //bolas há na caixa, mas poderiamos perguntar por qualquer
               //outro objeto.
               CaixaSurpresa<Bola> caixa = new CaixaSurpresa<Bola>();
               System.out.println("Há "+caixa.getObjetosSurpresa()
                .size()+" bola(s) dentro da caixa");
         }
   }

Centralizar para Facilitar

É muito comum vermos projetos com diversos códigos espalhados, que fazem exatamente a mesma coisa. Isso ocorre principalmente quando estamos trabalhando com projetos que possuem mais de uma pessoa envolvida, pois uma desenvolve uma lógica em uma local e outra pensando que já não foi desenvolvido, criando a mesma coisa, mas em outro local.

A dica aqui é centralizar lógicas que serão utilizadas em muitos locais do sistema em uma classe Helper. Assim sendo, todos procurarão dentro do seu Helper antes de criar um novo método que faça a mesma coisa. Sistemas bem projetos tem classes como: CalculosDeImpostosHelper, ConversorDeDatasHelper, ConversorDeUnidadesHelper e assim por diante.

Você já deve ter percebido, apenas pelo nome, o que cada classe faz, então se você é novo em um projeto que já tem um tempo de “estrada”, obviamente você procurará dentro da classe CalculosDeImpostosHelper antes de criar um método para calcular um ICMS de um produto, certo? Não é regra, mas geralmente as classes Helper's tem seus métodos com a assinatura “public static”. Veja um exemplo na Listagem 2.

Listagem 2. Criando um Helper para centralizar código


  public class CalculaImpostosHelper {
         
         public static double getBaseCalculoIcms
          (double frete, boolean fonteManaus, List<Produto> produtos,
                      double aliquotaIcms){
               
               //Realiza os calculos necessários aqui e retorna um double
               
         }
         
         public static double getBaseCalculoPis
          (List<Produto> produtos, double aliquotaPis){
               
               //Realiza os calculos necessários aqui e retorna um double
               
         }
         
         //E assim por diante...
   
  }

Classes enxutas

Isso mesmo, nada de classes com dez mil linhas de códigos para mostrar que você teve muito trabalho. Trabalho mesmo você terá após cinco anos, quando precisar dar manutenção nesta classe e não encontrar o que está procurando.

Use o velho conceito de “Dividir para Conquistar”, quando você perceber que sua classe está ficando muito grande, comece a criar classes auxiliares, helpers, mas tire toda carga extra da sua classe principal.

Um exemplo muito simples: se você está construindo uma classe que fará um CRUD de Funcionários, você não deve colocar nela cálculos de folha de pagamento, impressão de crachá, entre outras funcionalidades que fogem ao foco inicial que era apenas um CRUD.

Comentários Úteis

Este é um erro comum e quase frequente em muitos códigos onde você vê milhões de comentários, mas 90% deles são inúteis. Vamos explicar através da Listagem 3.

Listagem 3. Evite comentários inúteis


   
  public class MinhaClasse {
         
         public static void main (String ... args){
               
               double valor1 = Math.PI;
               
               //Soma valor 1 mais 10
               /*
                * Comentário totalmente desnecessário, afinal
                * está explícito que o valor1 será somado à 10.
                *
                * Em vez disso, explique porque o valor1 será somando à 10.
                * Ex: O valor1 será somado à 10 pois há um divergência 
                 * de 10 unidades nos produtos.
                * */
               double valor2 = valor1 + (10);
         }
   
  }

Comentário é um artifício ótimo quando utilizado da forma correta, porém a utilização de comentários desnecessários acaba tornando seu código ainda mais complexo de entender, pois ele se torna mais extenso, ou seja, a leitura se torna impraticável.

Não 'formate' (identar) o código de outra pessoa

Essa dica vale para quem trabalha em um mesmo projeto com mais pessoas, o que acaba causando problemas caso você não saiba a maneira certa de se portar quando analisa ou refatora o código de outro profissional.

É muito comum, ao estar trabalhando com classes desenvolvidas por outras pessoas, você perceber falta de identação, não por descuido do outro profissional, mas talvez pela configuração da IDE dele ser diferente da sua, ou seja, a identação que ele aplica é diferente da identação que você aplica. O aconselhável jamais identar códigos de terceiros, a não ser que o mesmo permita.

Imagine você que desenvolve a classe Y e passa para outro profissional criar um método ABC, então quando ele devolve a classe Y, você percebe que sua classe está totalmente diferente, apenas porque ele fez uma identação completa do código.

Pode parecer até absurdo tal característica ser foco em nosso artigo, mas na verdade ela é indispensável no dia a dia do trabalho em grupo, caso contrário, você terá muita dor de cabeça com esse tipo de problema. Vamos ver um exemplo na Listagem 4 de dois códigos idênticos, mas com identações distintas.

Listagem 4. Identações distintas no mesmo código


   /*
  * Código identado pelo profissional P1
  */
  public class Identado {
   
         /**
          *
          */
         private static final long serialVersionUID = 1L;
         int width, height;
         int x, y;
         int mx, my;
   
         public void init() {
               int valor1 = 0,valor2 = 0,valor3;
               
               double valorA1 = 0,valorB2 = 0;
               
               
               if (valor2 > 10)
               System.out.print(valor1 + valorA1+ valorB2);
         }
   }
   
  /*
  *  Mesmo código identado pelo profissional P2
  */
   
  public class Identado {
   
         /**
          *
          */
         private static final long serialVersionUID = 1L;
         int width,
               height;
         
         int x,
               y;
         
         int mx,
               my;
   
         public void init() {
               int   valor1 = 0,
                             valor2 = 0,
                             valor3;
               
   
               double
                             valorA1 = 0,
                             valorB2 = 0;
               
               
               if (valor2 > 10){
               System.out.print(valor1 +
                      valorA1 + valorB2);
               }
         }
  }

O exemplo acima é bem simples e acaba não causando tanto impacto, mas imagine uma classe com muitas linhas de código com todas essas diferenças de identação aplicadas. Com certeza causará uma grande dor de cabeça para o desenvolvedor da classe que terá o trabalho para encontrar suas lógicas que antes já estavam localizadas em pontos específicos.

O foco principal deste artigo foi demonstrar pontos chaves para o desenvolvimento de bons projetos, tentando abstrair ao máximo a tecnologia e ferramentas. Assim você pode aplicar esses conceitos nas mais diversas linguagens, não apenas em Java como foi demonstrado neste artigo.

O mais interessante neste artigo é a explicação e exemplificação de assuntos e “manias” que podem prejudicar todo um projeto.