quinta-feira, 8 de novembro de 2007

@Order

O Merlin é baseado em anotações. De fato, as anotações já existentes na própria linguagem Java e as definidas pelas especificações Java EE mais as do Hibernate também são reaproveitadas sempre que possível. Não obstante, as ainda no forno JSR 295 (Beans Binding) e a JSR 299 (Web Beans - aka Seam), também serão assim que a estabilidade as alcançe.

Entretanto, elas não são anotações para especificar interfaces de usuário (IU). Assim, torna-se necessário complementos. Nesse sentido, o Merlin define um conjunto de anotações (ainda em construção) para esse propósito.

As anotações do Merlin são, via regra, abstratas. Em outras palavras, elas não visam elementos dependentes de toolkits gráficos ou plataformas. Por exemplo, uma informação order:before("nome") sobre a propriedade observacoes não diz nada além do óbvio: que a propriedade observacoes deve ser posicionada antes da propriedade nome quando uma tela for gerada. Mas o que significa antes ?

Isso vai depender dos algoritmos de renderização atachados ao objeto. Se optarmos por algoritmos simples, como um FlowLayout() - semelhante ao FlowLayout do Swing, o TextArea com as observações (do Cliente, por exemplo) será mostrado à esquerda do seu nome. Se estivéssemos usando um GridLayout(), suas observações serão exibidas acima de seu nome, provavelmente.

Notem que tudo isso é bem subjetivo, tanto que termino a frase com um típico "ou não", como os mais chegados podem perceber. Mas isso está fora do escopo aqui, e vou explicar em momento oportuno.

A questão aqui é a seguinte: ao se definir as anotações necessárias, percebe-se que as variações existentes em uma IU são muitas. Enquanto que o mapeamento de herança para um modelo relacional pode ser feito de umas 5 formas diferentes, as possibilidades de mapear uma proprieade de um objeto para um controle de tela são, no mínimo, dezenas de vezes maiores. Se falarmos de posicionamento (layout), a coisa tende ao infinito. Tentar definir um denominador comum para as anotações para o Merlin pode ser muito dificil. Ou melhor dizendo, é inviável.

Então, o que fazer ? Ao invés de definirmos anotações específicas (como uma @Order, para o caso acima), podemos utilizar os seus próprios Agentes para isso. Vejamos um exemplo:

Hoje, o que existe é isso:

public class Cliente extends Pessoa implements PessoaFisica, PessoaJuridica {
String nome;
@Order(before="nome") String observacoes;
}

Já usando agentes:

public class Cliente extends Pessoa implements PessoaFisica, PessoaJuridica {
String nome;
@Agent({property="before=nome"}) String observacoes;
}

O que temos de diferente? No resultado final, nada. Mas como ganho em flexibilidade, tudo. Em outras palavras, a segunda alternativa reduz drasticamente o número de anotações necessárias para o Merlin, mantendo a mesma semântica de funcionamento. De quebra, também não perdemos em controle de sintaxe. Isso ocorre porque os parsers de código (futuros plugins para um Eclipse ou Netbeans da vida) vão pegar qualquer resbalada do programador.

Hoje, a versão alpha-1 do Merlin ainda é baseada na famigerada @Order. Mas depois de pensar bem no caso, e trocar uns contatos com alguns colegas (João, valeu; Mac, tu não conta!), a versão baseada em agentes será a opção do projeto.