Reduzindo o Tamanho de Métodos

a) Smell a ser reduzido/eliminado: Long method

b) Ingredientes

Ferramentas

Métrica(s) associada(s) número de linhas por método (Method Lines of Code – MLOC)

 Técnicas

Mecânica

  1. Identificar pontos onde o smell ocorre (PMD com Maven)
  2. Garantir que todas as ocorrências de código duplicado tenham um nível satisfatório de cobertura de testes (uso do JaCoCo)
  3. Caso a cobertura não esteja satisfatória, escrever testes unitários que garantam o comportamento (introduzir mais testes com JUnit, acompanhando sua cobertura com JaCoCo)
  4. Aplicar as técnicas de refactoring
  5. Rodar métricas novamente para verificar a melhoria
  6. Repita o passo 1

c) Aplicando a Receita no Projeto Spark

Base de código: Spark (http://www.sparkjava.com/)

Repositório utilizado: https://github.com/carlosaml/spark

Configuração de ferramentas

  • Maven utilizado para o build
  • PMD configurado para detectar métodos com mais de 50 linhas
  • Testes JUnit rodando atráves do Maven
  • JaCoCo plugado no Maven para geração de relatórios de cobertura de testes

Aplicação da Receita

Executando o build do Maven, o relatório do PMD acusa que o método boolean matchPath(String path) da classe spark.route.SimpleRouteMatcher é muito longo. Utilizaremos ele como base para a aplicação desta receita.

O método em questão é privado e chamado apenas por outro método privado, boolean matches(HttpMethod httpMethod, String path). Este, por sua vez, é utilizado por dois métodos públicos: RouteMatch findTargetForRequestedRoute(HttpMethod httpMethod, String path) e List<RouteMatch> findTargetsForRequestedRoute(HttpMethod httpMethod, String path).

Olhando o relatório de cobertura do JaCoCo, podemos notar que ambos métodos possuem 100% de cobertura de teste, o que nos dá plena segurança em realizar mudanças nessa classe.

Grande parte do comprimento do método se dá devido a existência de bastante código dentro do condicional if (thisPathSize == pathSize) {} else {}. Neste caso o refactoring que melhor se adapta é o Decompose Conditional.

Ao analisar o código mais profundamente, percebe-se que o condicional existe para tratar paths específicos de maneira diferente de “wildcards”. Com isso, podemos extrair dois diferentes métodos, um para cada situação: matchesSpecificPaths para o primeiro caso e matchesWildCards para o segundo. Com isso, todos os métodos da classe se tornam menores e consequentemente mais manuteníveis. Abaixo, temos o resultado do relatório do PMD, executado novamente, garantindo a remoção do smell.

2 thoughts on “Reduzindo o Tamanho de Métodos

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s