Propagação de mudanças no código

Estou lendo o livro ‘Working Effectively With LegacyCode’ de autoria de Michael Feathers sobre como tornar código testável. Para Feathers,

Todo código sem testes é código legado

Essas são suas heurísticas para descobrir a propagação de mudanças no código:

  1. Identifique o método que vai mudar.
  2. Se o método tem valor de retorno, fique atento aos que o invocam.
  3. Repare se o método modifica variáveis de instância. Se ele modificar, olhe o método que usa essas variáveis e os métodos que usam esses métodos.
  4. Repare em superclasses e subclasses que utilizam essas variáveis de instância e métodos também.
  5. Olhe os parâmetros dos métodos. Veja se eles ou outros objetos que esses métodos retornam são utilizados pelo código que se você quer modificar.
  6. Procure por variáveis globais e regiões estáticas que são modificados nos métodos que foram identificados.
Compartilhe:
  • Twitter
  • Digg
  • del.icio.us
  • Reddit
  • Google Buzz
  • Google Bookmarks
  • Facebook
  • Technorati
  • StumbleUpon
  • FriendFeed
  • MySpace
  • Slashdot

Tags: , , ,

Um pouco de história de Java e JDBC

Um pequeno vídeo postado no Javalobby há um tempo atrás sobre a evolução da plataforma Java desde 1991. Vale a pena conferir.

Compartilhe:
  • Twitter
  • Digg
  • del.icio.us
  • Reddit
  • Google Buzz
  • Google Bookmarks
  • Facebook
  • Technorati
  • StumbleUpon
  • FriendFeed
  • MySpace
  • Slashdot

Tags: , , ,

Template para Log4J no Eclipse

Há um tempo atrás o Bruno me passou uma dica muito útil para se criar um template para o Log4J no Eclipse. Faça o seguinte:

  1. Vá em Window > Preferences > Java > Editor > Templates
  2. Clique em New
  3. Nos campos Name e Description, escreva, por exemplo, logger (este é o nome que será utilizado para invocar o template)
  4. No campo Pattern, digite:

    private static final Logger LOGGER = Logger.getLogger(${enclosing_type}.class);

  5. Clique em OK

A variável ${enclosing_type} referencia o nome da classe atual. Pronto, basta digitar logger na declaração da classe que um logger para a classe vai ser adicionado!

Compartilhe:
  • Twitter
  • Digg
  • del.icio.us
  • Reddit
  • Google Buzz
  • Google Bookmarks
  • Facebook
  • Technorati
  • StumbleUpon
  • FriendFeed
  • MySpace
  • Slashdot

Tags: , , , ,

Meu artigo MIMECORA-DS no Google Books

Googando o termo MIMECORA-DS, que é o nome do meu trabalho de conclusão de curso de pós-graduação, descobri que meu artigo publicado no FP-UML 2009 referente a esta abordagem está presente no Google Books, referente ao evento ER 2009!

O título do artigo foi A Collaborative Support Approach on UML Sequence Diagrams for Aspect-Oriented Software, que significa Uma Abordagem com Suporte Colaborativo em Diagramas de Seqüência da UML para Software Orientado a Aspectos. Neste artigo apresentamos uma extensão baseada no meta-modelo padrão da UML, para representar as interações objeto-objeto, objeto-aspecto e aspecto-aspecto no diagrama de seqüências da UML.

Parabéns a todos os que colaboraram para este trabalho, principalmente ao @ffs_ffs e ao @emguerra!

Compartilhe:
  • Twitter
  • Digg
  • del.icio.us
  • Reddit
  • Google Buzz
  • Google Bookmarks
  • Facebook
  • Technorati
  • StumbleUpon
  • FriendFeed
  • MySpace
  • Slashdot

Tags: , , , , , ,

Sobre programação em par

No meu trabalho utilizamos Scrum para gerenciar o desenvolvimento de novas funcionalidades do sistema e também programação em par, basicamente por 3 motivos:

  1. Disseminar o conhecimento da base de código
  2. Familiarizar-se com as regras do sistema
  3. Duas cabeças pensantes facilitam o desenvolvimento da tarefa

Eu não tinha tido a oportunidade de colocar esse tipo de técnica em prática anteriormente, mas tenho reparado como ela é importante e benéfica para um projeto. Algumas vezes sou eu quem está programando (papel conhecido como driver) e outras vezes sou o observador (observer). O observador tem a tarefa de realizar a revisão de código durante o desenvolvimento. Esse último ponto é muito importante: revisão de código.
Programação em par encoraja a revisão de código. Provavelmente você não teria a oportunidade de refatorar um código como você tem quando está pareando com alguém. Eu acho que revisão de código é importante pelos seguintes motivos:

  • Melhora a qualidade do código: são 2 pessoas pensando na mesma tarefa ao mesmo tempo
  • Surgem oportunidade de refatoração de código
  • Quando se tem o suporte de uma boa IDE (como o Eclipse), algumas refatorações (extração de classe, extração de método, etc..) são bem automatizadas
  • Código é mais lido que escrito: duas pessoas lendo o código podem aprender muito mais sobre o sistema
  • Novas idéias surgem em função de pontos de vista diferentes
  • Bugs podem ser resolvidos pela complemento de conhecimento dos pares sobre a base de código

E você? Qual sua experiência sobre a programação em par?

Compartilhe:
  • Twitter
  • Digg
  • del.icio.us
  • Reddit
  • Google Buzz
  • Google Bookmarks
  • Facebook
  • Technorati
  • StumbleUpon
  • FriendFeed
  • MySpace
  • Slashdot

Tags: , , , ,

Integrando JUnit e Hamcrest

Há uns tempos atrás comecei a testar o projeto Hamcrest junto com o framework JUnit para criar testes unitários mais legíveis.

O projeto Hamcrest foi criado para melhorar a legibilidade do código de testes. É um framework que facilita a criação de objetos do tipo matcher que combinam regras presentes em testes de unidade. Seguem alguns examplos para deixar a idéia mais clara:

   1 import static org.hamcrest.CoreMatchers.equalTo;
   2 import static org.hamcrest.CoreMatchers.is;
   3 import static org.junit.Assert.assertThat;
   4 
   5 @Test
   6 public void shouldBeTheSamePerson()
   7 {
   8     Person me = new Person( "Rafael" );
   9     Person theOther = new Person( "Rafael" );
  10     assertThat( me, is( theOther ) );
  11 }
  12 
  13 @Test
  14 public void shouldHaveFixedSizeNumbers()
  15 {
  16     List<Integer> numbers = Arrays.asList( 1, 2, 3, 4, 5 );
  17     assertThat( numbers.size(), is( equalTo( 5 ) ) );
  18 }

O primeiro exemplo checa se um objeto do tipo Person é igual a outro usando o método equals, que foi sobrescrito na classe Person. A sintaxe is define um matcher que é um sinônimo para is(equalTo(valor)). O segundo exemplo utiliza o matcher is(equalTo(valor)) para checar o tamanho de uma lista de inteiros de tamanho fixo. O método assertThat é usado em conjunto com o matcher is(equalTo(valor)), que faz com que as sentenças de teste se tornem mais legíveis.

Algo interessante é a possibilidade de customizar a API de matcher, extendendo-os, como este exemplo que testa se uma dada lista contém somente números pares:

   1 public class AreEvenNumbers extends TypeSafeMatcher<Collection<Integer>> {
   2 
   3     @Override
   4     public boolean matchesSafely(Collection<Integer> numbers) {
   5         for (Integer number : numbers) {
   6             if (number % 2 != 0) {
   7                 return false;
   8             }
   9         }
  10         return true;
  11     }
  12 
  13     @Override
  14     public void describeTo(Description description) {
  15         description.appendText("even numbers");
  16     }
  17 
  18     @Factory
  19     public static <T> Matcher<Collection<Integer>> evenNumbers() {
  20         return new AreEvenNumbers();
  21     }
  22 }

E abaixo temos dois testes que utilizam o novo matcher AreEvenNumbers:

   1 import static org.hamcrest.CoreMatchers.is;
   2 import static org.junit.Assert.assertThat;
   3 import static br.com.rafael.hamcrest.AreEvenNumbers.evenNumbers;
   4 
   5 @Test
   6 public void shouldHaveOnlyEvenNumbers()
   7 {
   8     List<Integer> numbers = Arrays.asList( 2, 4, 6, 8, 10 );
   9     assertThat( numbers, is( evenNumbers() ) );
  10 }
  11 
  12 @Test
  13 public void shouldNotHaveOddNumbers()
  14 {
  15     List<Integer> numbers = Arrays.asList( 1, 2, 4, 6, 8, 10 );
  16     assertThat( numbers, not( evenNumbers() ) );
  17 }

Estes dois testes utilizam o método estático evenNumbers que fabrica os matchers no código de teste. Note o uso do matcher not no teste shouldNotHaveOddNumbers para garantir que números ímpares não estão presentes na lista. Todos os testes usam a funcionalidade de import estático, que torna o teste mais limpo e claro sem o nome da classe para invocar o método.

Ainda não tive a oportunidade de testar os matchers Beans, Collections e Number nos testes unitários. Eu acho que eles deixam os testes mais claros e mais fáceis de mudar. E você? Já utilizou o projeto Hamcrest? Se você tem mais exemplos, poste-os aqui!

Compartilhe:
  • Twitter
  • Digg
  • del.icio.us
  • Reddit
  • Google Buzz
  • Google Bookmarks
  • Facebook
  • Technorati
  • StumbleUpon
  • FriendFeed
  • MySpace
  • Slashdot

Tags: , , , , ,