Java Annotations: directing, enabling?
Por Fabio Kung em 22/09/08Há algum tempo, quando trabalhava na Alemanha, costumava ter diversas conversas e discussões extremamente produtivas com um grande amigo e desenvolvedor, Tiago Silveira. Como não poderia deixar de ser, desenvolvimento de software era o preferido entre diversos assuntos interessantes.
Em uma de nossas conversas, falávamos sobre o uso de anotações em Java. A discussão foi tão produtiva, que chegamos a concordar que o uso de anotações pode ser encarado como atitude com relação ao desenvolvimento de software!
Foi o próprio Tiago que começou a falar sobre enabling vs directing e começamos a fazer algumas comparações com o uso de anotações em projetos famosos.
Anotações são apenas metadados (ou DecorativeData, como alguns podem preferir); informações extras sobre o código que está escrito. Eu costumo sempre fazer analogia com um post-it pendurado no meio do seu código fonte: anotações não executam código.
Na minha opinião, o bom uso de anotações segue o estilo “Enabling”. Não te direcionam para nenhum caminho, não indicam a execução de nenhum código. Pelo contrário, como metadados, apenas possibilitam diversos usos desta informação extra. Um bom exemplo seria a anotação @Entity, da Java Persistence API:
@Entity
public class Carro {
// …
}
Diversos frameworks e até outras partes do seu sistema podem usar esta informação extra como bem entenderem. O próprio hibernate usa esta informação para saber que se trata de uma classe persistente, que deve ter representação no banco relacional, um validador poderia usar esta informação para decidir que objetos desta classe devem ser validados, um framework de aspectos poderia decidir aplicar um aspecto nesta classe baseado nesta informação extra, entre diversas outras possibilidades. Um outro exemplo interessante poderia ser a anotação @Transient, da própria especificação JPA:
public class Bicicleta {
@Transient
private double velocity;
}
Você poderia usar esta informação para decidir não mostrar este campo na interface gráfica (web ou desktop). Pode usar esta informação extra até para decidir que este campo não será enviado em emails, nem incluso em logs. Frameworks de ORM como o hibernate aproveitam esta informação para ignorar o atributo e não incluí-lo em nenhuma tarefa de persistência.
Poderia dar mais inúmeros exemplos de bons usos de anotações. O mais importante é a idéia de que a anotação possibilita diversos usos e não direciona - não força - nenhum caminho. A anotação não está associada a nenhuma execução de código. Funciona mesmo como um simples post-it.
A atitude alternativa seria o pensamento “Directing”. Neste caso, a anotação está diretamente relacionada a execução de algum código e serve apenas para este fim. Exemplo:
public class Sistema {
@EnviaEmail(Emails.CONFIRMACAO)
public void cadastra(Usuario usuario) {
//…
}
}
Neste caso não há outro uso para esta anotação. Perceba que ela já pressupõe a execução do código de envio de emails. Te limita a um pensamento particular, para um uso específico. Talvez seja um caso exagerado, mas não há diferença alguma com a chamada direta do método que envia o email:
public class Sistema {
public void cadastra(Usuario usuario) {
mensageiro.enviaEmail(Emails.CONFIRMACAO, usuario);
// …
}
}
Em alguns casos pode ser bastante difícil, ou até subjetivo demais, decidir se o uso de uma anotação é directing ou enabling. Não acho que devemos tomar nada como verdade absoluta; o importante é ter consciência dos diversos pontos de vista diferentes. Assim podemos tomar as nossas decisões, sempre pesando vantagens e desvantagens.
E você, consegue lembrar de algum outro uso interessante de anotações? Enabling ou Directing?
A diferença entre enabling e directing é mais semântica. Você poderia pensar a anotação que enviar email como um enabling, por exemplo: http://pastie.org/277241
Abraço…
Comment by Marcos Silva Pereira — September 22, 2008 @ 6:19 am
Pelo que vi do VRaptor FrameWork, ele é bastante Directing, não?
Comment by Bruno Laturner — September 22, 2008 @ 4:21 pm
@Bruno Laturner
pode ser que sim Bruno. Em alguns casos sim, outros não. São pontos que podemos tentar melhorar em próximas versões.
@Marcos
concordo plenamente que a coisa é geralmente semântica. Mas nesse uso que você postou (@Notify) ainda me parece directing. Não tem diferença com a chamada de um método parecido com notifier.notify(NotificationType.CONFIRM);
Comment by Fabio Kung — September 23, 2008 @ 6:06 am
Fabio, uma vez fiz um “exportador genérico” que recebia todo mundo que implementava determinada interface e gerada um xls bonitinho de todos os métodos que tinham um @Report, pois não existia um padrão de quais dados seriam exportados, quem queriar ser exportado usada a anotação.
Na época eu achei até que ficou bonitinho rs… seria um exemplo de Enabling.
Comment by Luiz Aguiar — September 23, 2008 @ 9:59 am
Caros, directing também poderia considerar os Actions do Struts 2.
Parabéns pelo interessante post!
Comment by Pedro Cavaléro — September 24, 2008 @ 4:42 am
Então, fiz uma uma annotation no estilo directing onde vc anota suas classes de dominio com @Dependency e com alguns atributos dizia como buscar as listas que elas precisavam nas suas respectivas telas. Como é um projeto de gerenciamento de conteudo esse tipo de coisa muda muito e fazer essa programação é meio chata(repetitiva), acho que nesse caso foi uma boa solução, e poderia ser reaproveitada para outro tipo de view por exemplo.
Comment by Alberto — September 25, 2008 @ 10:25 am