# Revisão de Código - Checklist # Código ## Legibilidade do código - [ ] Identar e formatar consultas SQL / HQL; - [ ] Identar elementos que fazem parte do mesmo grupo; - [ ] Utilizar aliases (apelidos) compreensíveis, mas tentar mantê-los pequenos; - [ ] Utilizar palavras reservadas do SQL em maiúsculas (SELECT, FROM, AS, ON, etc); - [ ] Identar subselects; - [ ] Utilizar espaços em branco entre blocos grandes (entre selects de um UNION, por exemplo); - [ ] Utilizar nomes de variáveis de fácil entendimento; - [ ] Tentar evitar siglas; - [ ] Se a variável tem um escopo grande, seu nome pode ser maior; - [ ] Utilizar nomes dos métodos de fácil entendimento e que expliquem resumidamente o que o método faz; - [ ] Evitar construção de métodos muito grandes ; - [ ] Remover código não utilizado. Não deixar comentado; - [ ] Usar static imports nas funcões utilitárias mais utilizadas (isEmpty, validateRequired, geraStringIn, etc.); - [ ] Se permitido pelo projeto, não ter pena de reorganizar o código para ele ficar mais claro. ## Simplicidade do código - [ ] Profundidade: - [ ] Evitar cadeias muito profundas de IFs - [ ] Evitar cadeias muito profundas de FORs - [ ] Evitar cadeias muito profundas de abstração. Isso ajuda na organização, mas atrapalha a navegação do código. - [ ] Usar métodos que operam sobre coleções ao invés de loops; - [ ] Usar Sets quando fizer sentido; - [ ] Usar loops foreach (Pessoa p : pessoas) { ... } ao invés de iterators ou fors com índices, quando possível. ## Anti-patterns e code smells (más práticas) - [ ] Uso de objetos quando tipos primitivos bastam; - [ ] Uso de tipos byte e short sem necessidade. Usar um int será tão rápido quanto esses tipos e mais simples de se usar na linguagem. A economia de memória normalmente não vale a pena; - [ ] Uso de float; - [ ] Uso de loops em operações sobre doubles; - [ ] Uso de parâmetros posicionais (em rowmappers, em arrays de objetos digiridos por int, etc); - [ ] Uso de consultas dentro de loops; - [ ] Criação de variáveis dentro de loops; - [ ] Números mágicos. Sempre usar constantes pré-existentes ou criá-las quando não existirem; - [ ] Esconder a interface de um método dentro de um objeto passado para ele; - [ ] Código duplicado; - [ ] e.printStackTrace(); - [ ] N+1 select (findByPrimaryKey, consultas sem projeção). ## Comentários no código - [ ] Comentar somente o que não for óbvio; - [ ] Comentar o "porquê", não o "como"; - [ ] Sempre comentar algo que seja contraintuitivo; - [ ] Não incluir anotações de @param, @throws, @deprecated e @return se não for documentá-las; - [ ] Utilizar Javadoc somente onde se aplica; - [ ] Não usar no corpo de método; - [ ] Não usar no cabeçalho do arquivo; - [ ] Incluir comentário do cabeçalho do arquivo: > Universidade Federal do Rio Grande do Norte Superintendência de > Informática Diretoria de Sistemas > > Criado em DD/MM/AAAA ## Formatação do código - [ ] Formato Java padrão; - [ ] Tabs para identar; - [ ] Identação correta; - [ ] Linhas com até 120 caracteres; - [ ] Uso correto de espaço em branco; - [ ] Retirar imports não utilizados (Ctrl+Shift+O). ## Exceções - [ ] Catch somente quando fizer sentido; - [ ] Não silenciar exceções; - [ ] 90% dos catchs são em NegocioException na camada de visão (MBeans); - [ ] O restante dos catchs em sua maioria é só para transformar uma exceção checked em ArqException; - [ ] Priorizar o registro de uma exceção (i.e. deixar a arquitetura tratar, na maioria dos casos) ao invés da exibição ao usuário; - [ ] Não mostrar para o usuário exceções que não são de negócio; - [ ] Não transformar NegocioException em outros tipos de exceção e vice-versa; - [ ] Não usar exceções para controle de fluxo; - [ ] Não utilizar e.printStackTrace() em catches de NegocioException. ## Elementos específicos ### Classes de domínio - [ ] Nome da classe é o nome comum do domínio; - [ ] Classes devem conter comentários; - [ ] Comentários da classe indicam o que o conceito faz (não simplesmente "Classe que representa X"); - [ ] Incluir campos utilitários quando fizer sentido: - [ ] boolean ativo - [ ] Date criadoEm - [ ] Date atualizadoEm - [ ] Utilizar anotações da arquitetura; - [ ] @Id - [ ] @CriadoPor - [ ] @CriadoEm - [ ] @AtualizadoPor - [ ] @AtualizadoEm - [ ] @CampoAtivo - [ ] Os nomes dos campos da classe representam bem os conceitos; - [ ] Se a entidade representa uma lista de tipos fixos que não serão modificados, pode-se utilizar um enum para as constantes (usar @Enumerated(EnumType.ORDINAL) no campo); - [ ] Evitar o uso do FetchType.EAGER no mapeamento, utilizar apenas com um ótimo motivo; - [ ] Herdar de Validatable; - [ ] Implementar validate(); - [ ] Método validate não acessa o banco - [ ] Método validate utiliza os utilitários de ValidatorUtil - [ ] Implementar equals (a arquitetura já fornece o EqualsUtil); - [ ] Implementar hashCode (a arquitetura já fornece o HashCodeUtil); - [ ] Implementar toString (facilita no debugging); - [ ] Implementar compareTo, se fizer sentido; - [ ] As classes devem estar localizada no pacote de domínio; - [ ] As classes persistíveis devem ser incluídas no hibernate.cfg.xml; - [ ] As únicas dependências da classe são de outras classes de domínio ou de funções utilitárias que não acessem o banco; - [ ] Não há dependência de banco na classe; - [ ] Não há acesso a ParametroHelper.getParametro(); - [ ] O acesso a campos em métodos utilitários sempre tem verificação de valores ; - [ ] Não se deve inicializar campos com objetos vazios somente para facilitar a vida nos MBeans, pois isso atrapalha o Hibernate. ### Processadores - [ ] Sempre verificar o comando que foi passado. Não deixar um else para o comando que "sobrou"; - [ ] Realizar todas validações. Evitar validar no Managed Bean. ### Helpers e classes utilitárias - [ ] Evitar criação de novos helpers para não "inchar" o gerenciamento de memória; - [ ] Evitar usar variáveis estáticas. Os métodos utilitários são chamados em paralelo pelas threads de cada usuário do sistema. #### Classes utilitárias - [ ] Verificar se já existe função similar na API Java, no Apache Commons ou Google ; - [ ] As funções/métodos não devem depender de estados fora da função (com a única exceção de acesso ao banco); - [ ] Algumas funções utilitárias da arquitetura têm deficiências e devem ser evitadas (observar as anotações @Deprecated); - [ ] Deixar a saída da função dependente somente das entradas, se possível. ### DAOs - [ ] Usar "Dao" no final ao invés de DAO. Isso evita nomes difíceis de ler: BuscaCnpjDao ao invés de BuscaCNPJDAO; - [ ] Colocar no pacote do módulo. Não colocar no sourcefolder/pacote "arq_dao"; - [ ] Sempre que puder, implementar consultas projetadas; - [ ] Utilizar HibernateUtils.parseTo() quando puder. ### Managed beans - [ ] Evitar a todo custo usar o escopo "session"; - [ ] Não reutilizar variávels para funções diferentes; - [ ] Não misturar filtros e campos de cadastro/alteração; - [ ] Não utilizar os campos da variável obj nos filtros. ### Timers - [ ] Evitar tratar exceções e enviar alertas de erro manualmente; - [ ] Evitar o uso de println()s, pois são desestruturados e nem sempre aparecem no log; - [ ] Usar uma transação geral para todos registro somente se necessário; - [ ] Limitar a quantidade de processamento feita em cada execução do timer, se for o caso, processar em lotes; - [ ] Enviar emails/alertas somente ao final do processamento de cada registro (se essa não for a única função do timer). ### Codificação de caracteres - [ ] Garantir que o projeto esteja configurado para a codificação correta. Não depender do default do Eclipse; - [ ] Não salvar arquivos na codificação incorreta; - [ ] Não tentar alterar codificação no meio de um processamento. Somente tratar codificação na entrada e saída de dados. Strings em Java sempre são UTF-16: não tentar salvar dados em outras codificação numa string. ### JSP / JSF - [ ] Evitar usar AJAX caso simplesmente esconder/mostrar elementos já resolva o problema; - [ ] Não importar o JQuery se não for necessário. O Prototype que já é incluído já tem todas funções básicas do JQuery e com praticamente a mesma sintaxe; - [ ] Limitar as linhas a 120 caracteres, preferivelmente; - [ ] Incluir ids nos elementos JSP/JSF; - [ ] Incluir titles nos campos. # Checklist de verificações antes da solicitação de integração - [ ] Conferir se a solicitação descrita na tarefa foi implementada corretamente; - [ ] Verificar e corrigir possíveis impactos causados pela modificação realizada (notificar ao analista de requisitos); - [ ] Verificar acesso à funcionalidade (verificar papéis de acesso); - [ ] Para o cenário em que existe formulário de consulta/geração de dados: - [ ] Verificar valores padrão dos campos ao entrar no caso de uso - [ ] Verificar validação de campos obrigatórios - [ ] Verificar mensagens de validação dos demais campos - [ ] Para campos autocomplete: - [ ] Verificar se os dados são retornados corretamente - [ ] Verificar tipo de dados aceitos em cada campo (só inteiros, tamanho máximo/capacidade, máscara); - [ ] Verificar padrões de layout em [1](https://docs.info.ufrn.br/doku.php?id=desenvolvimento:processo_trabalho:equipe_controle_de_qualidade:padroes_layout) [2](https://docs.info.ufrn.br/doku.php?id=desenvolvimento:processo_trabalho:equipe_controle_de_qualidade:padroes_desenvolvimento); - [ ] Testar filtros individualmente e combinados; - [ ] Verificar desempenho da funcionalidade criada (até 5 segundos); - [ ] Para o cenário em que existe relatório/comprovante gerado: - [ ] Verificar padrões de layout em [2](https://docs.info.ufrn.br/doku.php?id=desenvolvimento:processo_trabalho:equipe_controle_de_qualidade:padroes_desenvolvimento) [3](https://docs.info.ufrn.br/doku.php?id=desenvolvimento:processo_trabalho:equipe_controle_de_qualidade:padronizacao_relatorios); - [ ] Verificar se os filtros utilizados na geração dos dados aparecem no cabeçalho do relatório - [ ] Verificar proteção contra F5/duplo clique (prepareMovimento); - [ ] Verificar tratamento de exceções para exibir mensagens amigáveis ao usuário (no caso de exceções de negócio); - [ ] Caso não tenha feito, enumerar os principais cenários de teste baseado nas regras de negócio estabelecidas e testá-los; - [ ] Identificar o propósito da modificação solicitada para preencher o changelog; - [ ] Verificar se a especificação da funcionalidade está atualizada; - [ ] Verificar se é exibida mensagem de alerta ao usuário quando botão voltar do navegador for usado e operação confirmada novamente; - [ ] Caso exista scripts de banco, criar os scripts de acordo com o padrão utilizado do flyway; - [ ] Verificar se a funcionalidade desenvolvida está funcionando corretamente no ambiente em que irá ocorrer o teste (após o deploy). # Elementos extra-código ## Tarefa - [ ] Changelogs claros; - [ ] Changelogs que realmente refletem o que foi feito nas revisões. ## Commits - [ ] Verificar se não faltou algo ser *comitado*; - [ ] Verificar se há arquivos que só tiveram alterações de espaço em branco; - [ ] Comitar código comentado apenas com um bom motivo; - [ ] Verificar se adicionou arquivos de configuração, a não ser que seja necessário. ## Solicitação de teste - [ ] Log de solicitação de testes existe; - [ ] Log contém claramente o que foi feito na tarefa. ## Referências [1] https://docs.info.ufrn.br/doku.php?id=desenvolvimento:processo_trabalho:equipe_controle_de_qualidade:padroes_layout [2] https://docs.info.ufrn.br/doku.php?id=desenvolvimento:processo_trabalho:equipe_controle_de_qualidade:padroes_desenvolvimento [3] https://docs.info.ufrn.br/doku.php?id=desenvolvimento:processo_trabalho:equipe_controle_de_qualidade:padronizacao_relatorios [4] Clean Code by Robert C. Martin - https://www.oreilly.com/library/view/clean-code/9780136083238/ [5] Code smells - Coding Horror (http://blog.codinghorror.com/code-smells/) [6] Code smells - Wikipedia (https://en.wikipedia.org/wiki/Code_smell) [7] Coding conventions for the Java programming language (http://www.oracle.com/technetwork/java/codeconvtoc-136057.html) [8] Google Java Style (https://google.github.io/styleguide/javaguide.html) [9] A Taxonomy for “Bad Code Smells” (http://mikamantyla.eu/BadCodeSmellsTaxonomy.html) http://pt.slideshare.net/inaelrodrigues1/codigo-limpo-cap-2