quarta-feira, abril 20, 2005

Anotações no Tiger

Comecei a usar com mais força alguns recursos do Tiger, a nova versão de Java, e apesar de à primeira vista algumas coisas terem jeitão de sugar syntax, a maioria das inovações deixou a linguagem bem mais prática. O loop for a lá foreach é um exemplo disso porque não chega a inovar, mas apenas melhorar, iterações sobre arrays ou coleções de objetos. Lembro que quando comecei a programar em Java eu detestava ter que fazer algo assim:
List objects = ...
...
Iterator iterator = objects.iterator();
while(iterator.hasNext()) {
Something some = (Something)iterator.next();
...
}
Claro, depois que descobri a maneira "correta" de se fazer isso era:
List objects = ...
...
for(Interator it = objects.iterator();it.hasNext();) {
Something some = (Something)iterator.next();
...
}
Não chega a ser tão diferente do while, e também, não tem a legibilidade de um foreach:
List objects = ...
for(Something some: objects) {
...
}
Bem melhor, não?! Mas, até agora a feature que tem sido mais útil para mim são annotations. Poder dar a uma classe, metodo, atributo, parametro, whatever mais informações do que apenas um nome e tipo é algo extremamente poderoso. Agora, por exemplo, estou trabalhando em um pequeno conjunto de anotações que me permita traduzir atributos de uma classe para campos de um documento do Lucene. Já havia feito algo semelhante com reflexão apenas, mas o treco fica tão genérico que chega a não valer a pena já que trato todos os atributos de maneira completamente uniforme. Decidi então criar a seguinte anotação:
@Documented
@Target( ElementType.FIELD )
@Retention( RetentionPolicy.RUNTIME )
public @interface LuceneField {

String name();
boolean index() default true;
boolean store() default false;
boolean tokenize() default true;
float boost() default 1.0f;

}
Com ela posso descrever os atributos de uma classe num nível de granularidade impossível de ser alcançado apenas com reflection. Para exemplificar, vejamos a seguinte classe:
public class People implements Serializable {

@LuceneField(index=true,
tokenize=false,
store=true,
name="peopleid")
private Long id;

@LuceneField(index=true,
tokenize=true,
store=true,
name="peopleName")
private String name;

@LuceneField(index=true,
tokenize=false,
store=true,
name="peopleEmail")
private String email;

// some stuff

}
Depois, uma helper class traduz objetos dessa classe e de qualquer outra que use as anotações para um Document. Bem legal e relativamente fácil de implementar. Há ainda outras anotações, mas eu mostro depois quando a idéia estiver mais amadurecida. Para escrever essa tralha toda baixei o Eclipse3.1M6 que também tem boas novidades e as incompatibilidades de sempre com plugins feitos para a versão anterior. Por falar em forward/backward compatibility, esse é um dos problemas com o código atual que estou produzindo, nem adianta MESMO tentar usar em uma versão anterior do Java. De qualquer modo, como estou em um ambiente muito controlado, não vale a pena esperar (mais ainda) para usar as novas features em aplicações reais.

valeuz...

quinta-feira, abril 14, 2005

dois mil anos de invenções.

"Qual é a mais importante invenção dos últimos dois mil anos?" Essa é a pergunta que uma série de "cientistas da terceira cultura" ligados ao EDGE tentaram responder e deu origem ao livro "As Maiores Invenções dos Últimos 2000 Anos". Há algumas sugestões bastante peculiares como "a borracha de apagar", "a musica clássica ocidental" e outras. Ainda, detalhes interessantes como alguns darem sugestões completamente desligadas a area em que atual. Mas há também, respostas que indicam invenções mais ao alcance de todos, como a televisão, a imprensa e a Internet. E minha resposta para a pergunta passa por essas três ultimas. Para mim, a mais importante invenção dos últimos dois mil anos tem raízes em um espaço de tempo maior do que o proposto pela pergunta e não se trata de um objeto ou máquina, mas sim de um conceito. E a resposta é a "divulgação da informação" que, notadamente, surgiu, talvez por instinto ou não, nas pinturas rupestres. Alguns antropólogos e arqueólogos vêem as pinturas rupestres não como uma maneira de divertimento ou arte e sim como um registro das atividades e métodos para, por exemplo, realizar caçadas e rituais. É bem natural que o homem tenha percebido que era bem mais interessante registrar como se caça, como o fogo surge, ou como os rituais eram feitos do que ensinar tudo de maneira tácita.

E depois, a necessidade de transmitir informação se desenvolveu das paredes para os papiros, destes até chegar ao papel, e da escrita à mão até à imprensa de Gutenberg. E aí, a imprensa deu velocidade antes não imaginada a capacidade de divulgar informação. Ora, prensar livros em série ao invés de escrevê-los é algo infinitamente mais prático por uma série de motivos óbvios. Depois de todas as evoluções feitas à técnica, impressão em jornais, melhores papéis, impressão à cores, surge outro meio de informação: a tv! Claro, antes outros, o rádio e o telegrafo, mas nenhum com poderes próximos ao da televisão. E não conseguiriam, não com a televisão dando capacidade de ver e ouvir ao mesmo tempo, atingindo mais sentidos, o impacto do assistir, de ver, afinal, "o que eu escuto, eu esqueço; o que eu vejo, eu lembro". E eis que a velocidade para fazer a informação circular cresce em curva vertiginosa novamente. Com ela, a TV, foi possível saber, ver, alias, o que se passava em outros cantos do planeta. E criou-se, a meu ver, efetivamente, o que Pierre Levi chama de desterritorialização, você não pensa mais tão fortemente onde os fatos, a informação, ocorreu. Pensa, isso sim, "eu vi na televisão." Não pensa, a priori, de onde a informação está vindo, pensa para onde está indo, para a televisão. Pensa nos canais antes de pensar nos locais.

E, por fim, depois das transmissões a satélite, das manchetes depois do jantar, surge a Internet, filha da ARPANET (neta, ou a versão amadurecida da coisa, sei lá, ora bolas), com informações mais desterritorializadas ainda, eu não penso onde o Google está, fisicamente falando, claro, e sim no endereço que devo acessar, se está nos EUA, no Canadá ou na Conchinchina, não me importa, importa o endereço. Mas, mais do que isso, a Internet mudou também, ou melhor, deu maior velocidade, a geração da informação. Não são mais apenas escritores, repórteres, mulheres do tempo a me dizer o que se passa. Sou eu escrevendo em um blog, tenho minha página na Internet onde gero tanta informação (e lixo) quanto sou capaz. São, pelo menos 50 bilhões de páginas, e o numero aumento, lá vamos nós, vertiginosamente. Talvez como não se tenha visto na imprensa e na televisão. Nem poderia ser!

Afinal, os tempos são outros, mas as razões, a meu ver ainda são as mesmas. Os meios evoluíram com a própria humanidade. Antes, apenas se preocupar com a caça e com o grupo, então para que diacho publicar livros? Depois, tribos, cidades, castas, hierarquias, não dava para dizer "ei, cruza o mar e vem aqui sacar o que escrevi na minha caverna", então, a escrita em papiro, papel, mais simples de transportar do que uma caverna (leitor, essa é a única certeza nesse texto, o resto são especulações de uma mente pouco saudável). Os livros supriram a necessidade dos países, nos continentes, a necessidade de bem mais gente no mundo. Escrever a mão era praticamente impossível já que não é um tipo de produção em série. A TV para um mundo já parcialmente globalizado, mais cidades, mais gente ainda. Era natural que surgisse um meio mais barato e rápido do que livros ou jornais impressos. E, por fim, a Internet, a World Wide Web, com implicações, ainda não decidi, além da transmissão de informação. Escolho a "divulgação da informação" porque acredito ser o alicerce para muitas outras das invenções descritas no livro. Até mesmo para a borracha de apagar!

ps.: Eu já até imagino Diego Salcedo vir aqui e dizer algo do tipo "Mas blá, a informação sempre esteve sobre o controle de alguem, do faraó, sei lá, e nem todos têm acesso." E eu digo, "porra bla, eu sei, quer dizer, lembrava mais não, mas sei. Escreve sobre então, carai!".

valeuz...

segunda-feira, abril 11, 2005

Lucene.

Para aproveitar um pouco melhor o pouco tempo livre das férias, resolvi escrever um artigo sobre o Lucene. Eu gosto bastante dessa API então, nada melhor do que aproveitar e escrever sobre. A idéia, na verdade, começou com um post na wiki de onde trabalho, mas eu confesso que não havia gostado do resultado. Aliás, escrevi na filosofia de wiki mesmo, "depois alguém melhora isso." Então, quando sugeri ao JavaFree que poderia criar um tutorial a partir da entrada na Wiki alguém teve a ótima idéia de tentar publicar na revista MundoJava, ao invés de apenas publicar no portal. Vamos ver, ainda não entrei em contato oficial com a revista, mas, espero conseguir a publicação e, se não conseguir, ao menos é um bom tutorial para o JavaFree.

valeuz...

Meu código, meu precioso código... ou nem tanto.

É quase regra um programador não gostar do código de outros a menos que esse se pareça com o seu e, também, achar seus códigos antigos ruins, o que é completamente natural se vc considerar que evoluiu um bocado desde os tempos em que escreveu aquelas linhas de qualidade duvidosa. Foi justamente essa a sensação que tive quando, muito por acaso, encontrei alguns códigos de um projeto do qual participei em 2000. Os códigos não eram todos meus, mas vou assumir a culpa já que eu poderia ter ajudado a tornar as coisas melhores. Havia tantas más praticas que ativar o PMD, Metrics e FindBugs fez o Eclipse travar.

Os problemas mais comuns eram programação baseada em classes e não em interfaces, blocos condicionais complicados, métodos gritando por refactoring, quebra total do MVC, hierarquias de herança completamente desnecessárias, muito código sem qualquer conhecimento de YAGNI, singletons adoidados, checked exceptions aos montes e outras esquisitices que não vou citar sob o risco de ser apedrejado nas ruas. Mas não dá para negar, minha atenção se voltou principalmente para a total falta de uso de componentes, frameworks ou bibliotecas de classes prontas. Pool de conexões manual, MVC manual, persistência via plain JDBC (não me lembro de ter visto outras aplicações que permitiam tanto SQL Injection), sequer uma ferramenta de automação, como o Ant, por exemplo, era usada.

Então, lá fui eu fazer algumas estatísticas superficiais: entre as minhas 401 classes (401 classe?! Meu Deus!), dividas em 60 pacotes, 131 eram... Exceptions, o que indica graves problemas. Não vou explicar o projeto, mas acreditem, 401 classes são demais e, quando mais de 30% das suas classes são Exceptions, pode acreditar, existe algo de muito errado. Pior ainda, NENHUMA era unchecked e, daí, o errado passa a podre. Outro erro crasso era a total falta de abstração. Mesmo onde existiam interfaces, e elas eram apenas 42, era fácil encontrar algo do tipo:
MinhaInterface bla = new MinhaClasse();
Ou seja, sem uma abstração para criar os objetos, não adianta muito ter interfaces. Mas isso é fichinha perto do método abaixo:

public void setValue() {
if (value == null) {
throw new IllegalArgumentException();
} else {
this.value = value;
}
}

Muito útil, não?! Bom, baseado no lixo que eram meus códigos, ficam algumas dicas: 1) Tente pensar de maneira simples; 2) Tenha em mente YAGNI (401 classes?! Humpf!); 3) Usar frameworks e libraries de terceiros não vai fazer mal algum, então pesquise antes de tentar implementar uma solução caseira; 4) pense um pouco antes de criar uma Exception filha que não acrescenta informação a Exception pai; 5) unchecked exceptions são geralmente uma alternativa interessante; 6) Cuidado com aquelas classes MinhasOperacoesMalucas ou similares, em especial quando elas contem comentários do tipo "LIXÃO DO CODIGO ANTERIOR". E ficam também algumas constatações: 1) Eu aprendi muito em fóruns, mas pesquisar me ensinou mais ainda; 2) mudar do JBuilder para o Eclipse e usar ferramentas para inspeção de codigo me fez bem; 3) ainda bem que inventaram container de IoC e AOP; 4) testes podem até parecer chatos, mas são legais; 5) não tive preguiça de ler documentações e livros como o Effective Java, então, considere se tornar um bom leitor de bons livros.

valeuz...