31 Mar
Um dos grandes problemas que enfrentamos no meu atual projeto na AdaptWorks foi descobrir qual o real encoding de páginas html arbitrárias.
Existem diversas causas para esse problema:
Depois de muito procurar, encontramos um projeto que usa diversas heurísticas para detectar o encoding correto do arquivo.
O ICU (International Components for Unicode) faz todo o trabalho pesado para a detecção do encoding, com mais confiabilidade do que os dados enviados pelo servidor ou especificados pelo criador da página.
Entre os vários usuários do ICU, estão Google, IBM e Apple.
Ele é meio chato de usar, mas vale a pena.
Posts Relacionados:
Acompanhe-nos por
RSS, por Email ou via Twitter.
Veja como ter um desconto no Dreamhost: um excelente servidor web.
24 Mar
Já faz um bom tempo que eu mudei o meu ciclo de desenvolvimento com testes do Red, Green, Refactor (ciclo tradicional de TDD) para algo um pouco diferente.
O que aconteceu foi que eu tinha muito problema para pensar nas unidades pequenas sem ter as unidades grandes. Ah? Basicamente eu não consigo pensar em como implementar sem estar resolvendo o problema.
Confuso ainda, certo?
Bom, digamos que eu queira implementar algo que transforme um html em uma árvore (basicamente, parsear html). Eu não consigo pensar em como eu faria para parsear a tag. Apenas consigo pensar em como funcionaria para o html. Algo como:
HtmlParseado html = new HtmlParser().
parse("<html><title>Conteudo</title></html>");
Somente no momento em que estou dentro do método parse que eu consigo pensar em como descobrir quais são as tags. Por que isso? Por causa da abstração.
No código acima não faz o menor sentido pensar nas tags, apenas no html completo. Dentro do método parse começa a fazer sentido procurar pelas tags.
Então o que tenho feito? Eu crio um ou mais testes que sobre a funcionalidade inteira (no caso, o que o parse deve fazer com o html).
Algo como:
@Test
public void testaQueOParserFunciona(){
HtmlParseado html = new HtmlParser().
parse("<html><title>Conteudo</title></html>");
Assert.assertEquals("html", html.getFirstChild().getTagName());
...
}
O problema é que esse teste é muito grande para guiar o desenvolvimento. O que eu faço então? Parto para o problema menor que é o reconhecimento de tags.
Como nesse ponto eu já consigo imaginar mais ou menos o que quero que aconteça, consigo criar os testes para fazer o reconhecimento de tags.
Mas durante todo esse tempo, o meu teste do ponto mais alto da abstração continua sem passar. Isso quebra com o RGR, mas me ajuda muito com o desenvolvimento da interface de uso.
Talvez eu tenha perdido um pouco na qualidade do código usando essa abordagem top-down, mas ganho bastante em termos de usabilidade desse código. Isso me força a pensar em primeiro lugar em como vai ser usada a funcionalidade final e não nos menores constituintes dela.
Outra coisa que esses testes me ajudam muito é a saber quando eu terminei a funcionalidade mais complexa.
O que acham disso? Já fizeram (ou fazem) algo semelhante?
Posts Relacionados:
Acompanhe-nos por
RSS, por Email ou via Twitter.
Veja como ter um desconto no Dreamhost: um excelente servidor web.
17 Mar
Lembro que em pelo menos um post anterior eu comentei sobre o Infinitest.
O Infinitest é uma ferramenta que roda seus testes unitários a cada vez que você salva algum arquivo. Mas ele não roda todos. Roda apenas os que são afetados pela modificação que você fez.
Isso é muito legal porque reduz muito o tempo de feedback. Imaginem, a cada vez que você salva o arquivo, teria que rodar todos os testes unitários (em geral é meio difícil saber se uma modificação afetou um teste ou não), o que pode demorar vários segundos em um projeto saudável. O infinitest te dá feedback quase instantâneo.
Outra coisa muito legal é que ele coloca um marcador de erro (sabe a marcação de erro de compilação do eclipse? pois é.) no teste que falhou ou onde foi lançada a exceção que impediu a execução do teste. Nem preciso dizer o quanto isso facilita para encontrar o problema.
A primeira versão (3.X) que usei dele, foi durante o desenvolvimento do Mirror. Na época era meio complicado colocar ele para rodar e tinha uns bugs meio estranhos (testes em loop infinito ficavam rodando eternamente). A versão atual (4.X) possui plugins para Eclipse e IntelliJ.
Vale muito a pena, em especial se você quer aprender TDD.
Posts Relacionados:
Acompanhe-nos por
RSS, por Email ou via Twitter.
Veja como ter um desconto no Dreamhost: um excelente servidor web.
10 Mar
Uma coisa que ouço sempre na comunidade Java (falo dessa pois é a que conheço melhor) são os brados de “não reinventar a roda”. Cada vez que alguém aparece com um problema e fala de uma solução que algum projeto já resolve, desincentivam o programador completamente, falando que não vale a pena resolver novamente o problema já resolvido.
Eu não tenho como discordar mais de uma afirmação como essa.
A maior parte do tempo que dedico ao desenvolvimento fora do trabalho eu estou reinventando rodas. O Mirror é um exemplo disso. Dá pra fazer quase tudo que ele faz usando a API de reflection nativa do Java, mas é muito mais trabalhoso. Se eu não decido que reinventar a roda era uma coisa boa, eu não teria uma forma melhor de trabalhar com reflection. Além de que meu conhecimento sobre reflection não seria um décimo do que é hoje.
Além disso, tem um problema maior. Quando você usa uma camada de abstração, você ignora o que está acontecendo por baixo dos panos. Muitas vezes isso é bem importante, mas é bem perigoso também porque abstrações vazam. Em algum momento você terá que lidar com a infraestrutura que está embaixo da abstração e nesse momento, conhecer como a roda foi criada é fundamental.
Então, ao contrário do que a maioria diz, eu reinvento a roda sempre que posso. Depois que está funcionando e tem uma boa cobertura de testes, se for melhor (na minha opnião) do que existe no mercado eu extraio e lanço opensource. Caso contrário, migro meu código para uma das soluções existentes. Gastei mais tempo? Não. Fiz um investimento em mim (e provavelmente na minha equipe). Me tornei mais capacitado para resolver esse e vários outros problemas.
Mas é bom lembrar que você não vai poder fazer isso sempre (afinal, não se vive apenas de investimentos). Sem contar que reinventar a mesma roda sempre é bobagem (você vai aprender muito menos do que reinventando uma roda nova).
Posts Relacionados:
Acompanhe-nos por
RSS, por Email ou via Twitter.
Veja como ter um desconto no Dreamhost: um excelente servidor web.