Monthly Archive for November, 2006

BTUF

Não precisa ler o título de novo. Seus olhos não estão enganados: realmente é um T no lugar do D (ou R, dependendo de onde você esteja vindo). BTUF é o acrônimo para Big Testing Up-Front. BTUF é o que acontece quando você tenta desenvolver todos os testes possíveis e imagináveis para seu código antes de começar a escrevê-lo. Com a popularização de Test-Driven Development esta é uma modalidade para cascateamento do desenvolvimento em óbvia ascensão.

Testar também é projetar. Quando se escreve os testes antes do código de produção o que se faz essencialmente é projetar como o código vai parecer olhando do lado de fora. Às vezes é difícil resistir à tentação de projetar tudo antes para depois partir para a implementação. Para quem não consegue evitar, aqui vai uma bela notícia do jornal de ontem: isso não funciona. Apesar de todo mundo minimamente informado já ter lido o jornal, nunca é demais repetir.

Não funciona porque projetar qualquer coisa é infinitamente melhor quando é possível obter retorno. Desenvolver software é uma das atividades que dispõem de maior capacidade de retorno em tempo de projeto. Arquitetos precisam esperar que a equipe de construção termine a obra, roteiristas de cinema podem esperar anos pelo término das filmagens e músicos precisam esperar por um longo processo de mixagem para saber como seus projetos serão apreciados pelo público. Mas programadores podem simplesmente compilar seus programas. Desistir propositalmente deste retorno não é algo muito sábio a se fazer. Escrever todos os testes para um trecho de código antes de escrever é como desenhar vários retângulos e setas descrevendo-o detalhadamente antes de tentar fazê-lo funcionar. O risco de hiper-engenharia é o mesmo porque o código não está lá para gritar de agonia.

Então se você leu o artigo do José Oliveira, considere com muito carinho os conselhos dele. Mas leia o esclarecedor artigo do Ivan Sanchez também. Escreva os testes que conseguir imaginar antes de começar a escrever o código para fazê-los passar, mas por favor não fique muito tempo pensando. Você pode esperar para começar a escrever o código depois que todos os testes estiverem prontos, mas você não precisa e nem quer fazer isso.

Design não se faz somente com diagramas e TDD é só uma técnica de design que usa testes. Pode ser uma abordagem bem mais eficaz que setas e retângulos em alguns casos, já que força o programador a utilizar o código ao mesmo tempo que o projeta. Mas ainda assim é somente uma abordagem para design. BTUF, do mesmo modo, é somente um caso especial de BDUF no qual se usa testes para explicitar completamente o design antes de se escrever qualquer linha de código.

Controle de versão distribuído se distribui

Talvez eu simplesmente tenha pegado o trem tarde demais e estou vendo como novidade o que os veteranos veriam como normalidade, mas tem algo que venho observando há algum tempo. Não vou chamar de tendência para não arriscar queimar a língua no futuro, mas é no mínimo curioso.

Você tem notado como os sistemas de controle de versão distribuídos estão mais comuns?

Há um ano e meio nós no projeto EclipseFP estamos usando um sistema distribuído chamado Darcs. Ele vem se tornando um tipo de padrão de fato na comunidade Haskell porque é escrito em Haskell. Apesar do nosso projeto (ainda) não ser totalmente escrito em Haskell, em geral é uma boa idéia para um ambiente de desenvolvimento se distanciar o mínimo possível da sua comunidade. A escolha então foi óbvia.

Isto não prova muita coisa. Estou falando do meu próprio projeto, afinal de contas. Mas tem mais. A menos que você estivesse em algum tipo de caverna em um planeta distante da Terra durante os últimos dois anos, você já ouviu falar no Ubuntu. Eles também usam um sistema de controle de versão distribuído, o Bazaar-NG (também conhecido por bzr). Outro projeto do qual você talvez já tenha ouvido falar que usa controle de versão distribuído é o Linux. Eles usam o git, que foi originalmente escrito por Linus Torvalds para ser usado no desenvolvimento do seu kernel. Há até um espelho Darcs do repositório deles. Como se não bastasse há ainda os boatos sobre a versão 2.0 do Subversion (conhecido também pela alcunha svn) ser distribuída.

Mas o que me chamou a atenção foi um pequeno detalhe da decisão da Sun de abrir o código de Java semana passada. Passaria totalmente desapercebido se não fosse minha interminável lista de feeds e seu inesgotável estoque de artigos interessantes. Acontece que eles também vão passar a usar mais um sistema de controle de versão distribuído. O nome dele é Mercurial. hg para os íntimos.

A pergunta de um milhão de dólares (ou de um milhão de olhos, como vou tentar mostrar) é: por que eles estão fazendo isso?

Com controle de versão distribuído, cada cópia de trabalho é um repositório completo. Ou seja, cada desenvolvedor ou curioso que queira acompanhar o projeto tem o histórico de modificações ao código-fonte armazenado localmente. Há dez anos não era todo mundo que tinha 40GB de memória de armazenamento disponível e fazia sentido recorrer a um servidor central para armazenar o histórico de um projeto. Hoje as pessoas podem se dar ao luxo de armazenar o histórico do Linux (hoje com mais de 300MB) sem problemas.

Tecnicamente não é necessário haver algo como um repositório central quando se usa controle de versão distribuído. Não há uma hierarquia de repositórios, cada um é independente dos demais. Se eu e você estamos trabalhando em um mesmo projeto, podemos fazer modificações separadamente o tanto quanto quisermos e ambos terão o mesmo poder sobre seu repositório local. Ambos poderão gravar alterações, desfazê-las e consultar o histórico do projeto como quiserem sem precisar saber o que acontece com o repositório do outro. Se quisermos, podemos mesclar os dois repositórios para sincronizá-los e isso faz muito sentido se estivermos realmente trabalhando no mesmo projeto. Como esta operação costuma ser freqüente, as pessoas em geral elegem um dos repositórios como central. Elas passam a enviar suas alterações para lá quando estão prontas para publicação e consultá-lo quando precisam atualizar suas cópias locais. Mas só porque escolheram fazê-lo. Não há nenhuma limitação do sistema que as obrigue a fazer isso.

Isto facilita muito a vida tanto de quem quer contribuir com patches como de quem precisa gerenciá-los. Se você fez uma modificação no código de algum projeto, tudo que você precisa é fazer um mini-fork fazendo uma cópia local do repositório e gravar sua alteração. Mais tarde, quando o corpo de código principal for modificado, o sistema vai se encarregar de juntar tudo sozinho. Com controle centralizado você precisa convencer os mantenedores que o seu patch é importante para que eles o integrem ao código principal ou se contentar em refazer as modificações a cada revisão. Claro que você vai gravar seus patches localmente para facilitar, mas as coisas podem ficar bem cabeludas se você tiver muitas alterações.

Ter um repositório completo local significa também que você pode gravar modificações intermediárias. Todo mundo faz besteira de vez em quando e é bom poder saber que há algo mais que a função de desfazer do editor para te proteger. Quando podem as pessoas tendem a fazer modificações menores e detalhar melhor seus comentários. Ao mesmo tempo que o colaborador externo tem mais controle sobre suas alterações, o mantenedor ganha um histórico de versões mais limpo, livre de revisões gigantescas.

Toda a razão para disponibilizar seu código-fonte livremente é poder contar com a força de uma comunidade. Quanto mais gente vir o código, melhor ele vai poder ficar. Patches são um dos maiores desejos de qualquer mantenedor de um pedaço de código e controle de versão distribuído facilita a vida deles e de quem quer contribuir. Quando se quer atrair contribuições, diminuir as barreiras para quem quiser contribuir não faz mal a ninguém e é justamente isso que a Sun está tentando fazer agora com o OpenJDK.