Dojo PHP no #guma10anos

Dia 4 de abril de 2014 ocorreu mais um evento do GUMA, sendo este especial pelo fato do mesmo estar completando 10 anos de existência, então o evento todo foi em ritmo de festa e comemorações.

Eu e o Guilherme Lacerda conduzimos um Dojo de PHP para a galera treinar um pouco de TDD, OO, comunicação e trabalho em equipe.

Abaixo seguem algumas fotos, bem como link para os slides e repositório com código fonte da solução para o problema proposto (Cifra de César).

Slides Repositório

 

 

 

Advertisements

Valeu CBSoft 2013!

Está acontecendo, de 29 de setembro a 04 de outubro, a 4a edição do CBSoft 2013, Conferência Brasileira de Software: Teoria e Prática, em Brasília.

O evento, que conta com vários cursos, workshops, tutoriais e simpósios em paralelo é o grande evento de Engenharia de Software no Brasil. Neste ano, eu e o Daniel representamos o CbE, ministrando um tutorial que leva o nome do nosso blog. Neste tutorial, discutimos a postura de um desenvolvedor profissional e o que é necessário para chegar lá, em termos de aprendizado.

No tutorial, é proposto um exercício prático de programação, onde o objetivo é treinar refatoração, baby steps, TDD e conhecer algumas ferramentas que fazem a diferença, como PMD, Checkstyle, Findbugs, JaCoCo, JUnit, Jenkins e Sonar.

Abaixo, colocamos uma foto para registrar o final do tutorial. Nosso muito obrigado a todos os participantes e a organização, em especial ao Prof. Ségio Soares, da UFPE.

Participantes do Coding By Example

Ah… e como prometido, disponibilizamos os slides no slideshare (apresentação e exercício proposto) e o código no github. Bom treino a todos!! 🙂

Reduzindo o Tamanho de Listas de Parâmetros de um Método

a) Smell a ser reduzido/eliminado: Long Parameter List

b) Ingredientes

Ferramentas

Métrica(s) associada(s): número de parâmetros por método (Number of Parameters in Method – PAR)

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 ArgoUML

Base de código: ArgoUML (http://argouml.tigris.org/)

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

Configuração de ferramentas

  • Maven utilizado para o build
  • PMD configurado para detectar métodos com mais de 6 parâmetros
  • 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 seguinte método recebe muitos parâmetros:

private String toString(Object modelElement, boolean useGuillemets, 

            boolean showVisibility, boolean showMultiplicity, boolean showTypes,

            boolean showInitialValues, boolean showProperties)

Portanto, utilizaremos ele como base para a aplicação desta receita.

Primeiramente verificamos a cobertura de testes dos chamadores deste método (pelo fato do mesmo ser privado), que é apenas um:

public String toString(Object modelElement, NotationSettings settings)

O relatório de cobertura de testes existente não passa a confiança necessária para que o método possa ser refatorado. Para melhorar este cenário, escreve-se mais testes para o método público.

Para isso, a classe TestAttributeNotationUml, contendo cinco testes unitários, é adicionada.

Com isso eleva-se a cobertura de testes e consequentemente consegue-se autorização para refatorar o método toString que conta com muitos parâmetros.

Procurando pelos usos do método em questão, vemos que existe apenas um e que este apenas extrai os valores de algumas propriedades do objeto NotationSettings recebido e os passa adiante. Isso define claramente um ótimo candidato para Preserve Whole Object, já que muitos dos parâmetros do método são fortemente relacionados.

Para isso, substituímos todos estes parâmetros:

  • boolean useGuillemets
  • boolean showVisibility
  • boolean showMultiplicity
  • boolean showTypes
  • boolean showInitialValues
  • boolean showProperties

Por apenas um:

  • NotationSettings settings

E mudamos a única chamada do método para que passe diretamente a instância de NotationSettings.

Com isso o PMD já não acusa mais o método em seu relatório.

Porém, o método recém refatorado conta com somente um uso, o que não faz sentido devido ao fato do mesmo ser privado. Para tanto, podemos aplicar Inline Method e eliminar o método privado em questão.

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.

Apresentação disponível: Trunk Based Development Explored (AgileBrazil 2011)

Já está disponível os slides da palestra realizada em Fortaleza, no AgileBrazil 2011. Em breve, disponibilizaremos também os exemplos de Feature Toggle. O mais legal é que, no mesmo dia de nossa palestra, Martin Fowler e Mike Mason gravaram um vídeo abordando o mesmo problema.

 

Atualização em 04/07:  Já estão disponíveis os exemplos de feature toggle.