segunda-feira, 28 de fevereiro de 2011

Sudoku Solver

Ontém, o amigo Edcana comentou no twitter que estava escrevendo um resolvedor de Sudokus. Sempre gostei desse jogo, mas nunca tinha passado pela cabeça em escrever um programa para resolvê-lo... E foi uma diversão interessante...

E foi uma diversão interessante... Abaixo uma versão parcial da aplicação, escrita em GWT, com 2 estratégias se solução (resolvem os níveis fácil e médio de problemas propostos no iGoogle). Já descobri uma terceira estratégia para resolver o nível hardest, mas ficará para a próxima semana.

O código está disponível em https://github.com/fabiolnm/Sudoku-Solver. A aplicação roda num iframe que mostra a app deployada no AWS (https://s3.amazonaws.com/mind_share/sudoku/index.html).

A primeira solução foi até tranquila... Porém o código mal-desenhado dificultou a adição de novas regras... Antes de conseguir adicionar uma segunda estratégia de solução, foi necessário fazer muitas refatorações no código. E sem testes, a solução de bugs só foi possível graças aos recursos de logging e debugging do plugin GWT para o Eclipse.

Nesta aplicação, me questinei se TDD seria útil... Minha compreensão sobre o problema mudou tanto e tantas vezes, que talvez se estivesse escrevendo testes antes, não teria conseguido avançar na velocidade desejada... Porém, quando precisei refatorar código, as alterações eram penosas. Sempre acrescentava bugs, que demorava para encontrar no debugger.

Entender melhor o domínio, e só depois de um certo ponto adicionar testes, seria um pattern ou anti-pattern? Argumento pró: acelerar tentativas e erros (TDD freia um pouco o processo de aprendizado?). Argumento contra: depois que a funcionalidade está escrita, dá preguiça de escrever teste...

Minha conclusão, depois desse problema, foi: não importa se vc faz testes antes ou depois. Antes de refatorar, escreva testes! O custo e o aborrecimento de quebrar funcionalidades justificam ter testes antes de qualquer modificação significativa do código.

É um bom momento, pois com uma aplicação minima rodando, alguns conceitos já foram provados, e os bad smells começam a ficar evidentes. E como não se quer quebrar nada a partir desse ponto, é uma motivação para começar a escrever testes, e através deles remover os bad smells e pogs inevitavelmente praticados durante a primeira prova de conceito da aplicação.

Um comentário:

  1. Caro Fábio, gostei muito das tuas breves considerações sobre o uso ou não do TDD. Concordo com teu posicionamento no último parágrafo.
    Na minha experiência escrever testes antes só funciona bem quando se tem um nível de entendimento grande dos universos problema/solução. Caso isso esse caso é uma exceção entendo que o método tradicional de tentativa e erro seja o melhor para acelerar o processo de construção de uma solução inicial e, com isso, conhecer melhor o problema. Depois deste ponto criar os testes tornan-se imprescindível para convergir para uma solução real mais rápido. Entretanto, vale ressaltar, que esse posicionamento é verdadeiro para projetos pequenos compostos por um poucos casos de uso e de baixa complexidade algorítmica. Quando há uma aumento significativo de escala e/ou complexidade fazer um planejamento e projeto mais aprofundado torna-se obrigatório.

    ResponderExcluir