# 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