Annotations poluem o codigo?

Vejam essas classes:

[code]@Entity( access = AccessType.FIELD )
@NamedQueries({
@NamedQuery( name = “Page.containsLabel”,
queryString = “” ),
@NamedQuery( name = “Page.findByUser”,
queryString = “” ),
@NamedQuery( name = “Page.findRootPages”,
queryString = “” ),
@NamedQuery( name = “Page.findWatchedPages”,
queryString = “” ),
@NamedQuery( name = “Page.findHotPages”,
queryString = “” ),
@NamedQuery( name = “Page.findBookmarkedPages”,
queryString = “” ),
@NamedQuery( name = “Page.findByDate”,
queryString = “” ), } )
@Filters( {
// a null status points out to a open page
@Filter( name = “Page.FilterDeleted”, condition = “status is null” ) } )
@LuceneAnnotation
public class Page extends LiberEntity<Page> implements Identifiable<Long> {

@Id( generate = GeneratorType.AUTO )
@Column( name = "page_id" )
@LuceneId( luceneId = "PageId" )
private Long id;

private int version;
private int views;
@LuceneField
private Calendar date;
@LuceneField( isContent = true )
private String title;

@Type( type = "text" )
@LuceneField( isContent = true )
private String text;

@OneToMany( fetch = FetchType.LAZY,  mappedBy="page" )
private Set&lt;Comment&gt; replies = new HashSet&lt;Comment&gt;();

@ManyToMany( fetch = FetchType.LAZY )
@AssociationTable( 
    table = @Table( name = "pages_labels" ), 
    joinColumns = @JoinColumn( name = "fk_page_id" ), 
    inverseJoinColumns = @JoinColumn( name = "fk_label_id" ) )
private Set&lt;Label&gt; labels = new HashSet&lt;Label&gt;();

@ManyToOne( targetEntity = "br.foo.bar.domain.User" )
@JoinColumn( name = "fk_user_id" )
private User author;

@ManyToMany( fetch = FetchType.LAZY )
@AssociationTable( 
    table = @Table( name = "pages_watchers" ), 
    joinColumns = @JoinColumn( name = "fk_page_id" ), 
    inverseJoinColumns = @JoinColumn( name = "fk_user_id" ) )
private Set&lt;User&gt; watchers = new HashSet&lt;User&gt;();

@ManyToMany( fetch = FetchType.LAZY )
@AssociationTable( 
    table = @Table( name = "pages_bookmarkers" ), 
    joinColumns = @JoinColumn( name = "fk_page_id" ), 
    inverseJoinColumns = @JoinColumn( name = "fk_user_id" ) )
private Set&lt;User&gt; bookmarkers = new HashSet&lt;User&gt;();

private String status;
private boolean acceptHtml;

// gets, sets, bla bla bla

}[/code]

[code]@Entity( access = AccessType.FIELD )
@NamedQueries({
@NamedQuery( name = “User.findByRole”, queryString = “” ),
@NamedQuery( name = “User.findByGroup”, queryString = “” ),
@NamedQuery( name = “User.findByStatus”, queryString = “” ),
@NamedQuery( name = “User.findMoreActive”, queryString = “” ),
@NamedQuery( name = “User.findLessActive”, queryString = “” ),
@NamedQuery( name = “User.findByRegisterDate”, queryString = “” ),
@NamedQuery( name = “User.findByLastVisitDate”, queryString = “” ),
@NamedQuery( name = “User.findAbsenteeUsers”, queryString = “” ),
@NamedQuery( name = “User.findByEmail”,
queryString = “select u from User u where u.email = ?” ),
@NamedQuery( name = “User.findByLogin”,
queryString = “select u from User u where u.login = ?” )
}
)
public class User extends NextEntity<User> implements Identifiable<Long> {

@Id( generate = GeneratorType.AUTO )
@Column( name = "user_id" )
private Long id;

@Column( nullable = false )
private String login;

@Column( nullable = false )
private String password;

private String name;
private String email;

@ManyToMany( 
    fetch = FetchType.LAZY, 
    targetEntity = "br.foo.bar.domain.Role" )
@AssociationTable( 
    table = @Table( name = "users_roles" ), 
    joinColumns = @JoinColumn( name = "fk_user_id" ), 
    inverseJoinColumns = @JoinColumn( name = "fk_role_id" ) )
private Set&lt;Role&gt; roles = new HashSet&lt;Role&gt;();

@ManyToMany( 
    fetch = FetchType.LAZY, 
    targetEntity = "br.foo.bar.domain.Group" )
@AssociationTable( 
    table = @Table( name = "users_groups" ), 
    joinColumns = @JoinColumn( name = "fk_user_id" ), 
    inverseJoinColumns = @JoinColumn( name = "fk_group_id" ) )
private Set&lt;Group&gt; groups = new HashSet&lt;Group&gt;();

@OneToOne( fetch = FetchType.LAZY )
@JoinColumn( name = "fk_status_id", nullable = false )
private Status status;

@Embedded
@CompositeField(
    attributes={
        @LuceneField(attribute="signature"),
        @LuceneField(attribute="profile"),
    }
)
private SecondaryInfo info;

// gets, sets, bla bla bla

}[/code]

E algumas observações:

  1. Acredito que depois de algum tempo, o Tiger se tornará padrão e annotations serão a maneira mais comumente usada para fazer o mapeamento com o Hibernate (e talvez outros concorrentes). Apesar de ser possivel mapear algumas classes com xml e outras com anotações, não me parece adequado misturar as duas coisas;
  2. NamedQueries, as quais podem conter hql muito grandes, podem ser colocadas em um package-info, então, elas não necessariamente ficarão nas classes de dominio, o que alivia a quantidade de annotations nessas classes;
  3. Em projetos maiores, outros conjuntos de annotations podem ser usados e a quantidade de metadados pode crescer um bocado;
  4. Eu acho annotations um recurso extremamente util;

E a pergunta, annotations são muito verborágicas e deixam o codigo poluido? Ou falta apenas se acustumar com elas?

valeuz…

Hibernate precisa de muita configuração. Já que há ferramentas para gerá-la quase toda para você, qual o problema de deixar no coitado do XML?

Código azul fede :expressionless:

Pode nao ter caido minha ficha ainda, mas acho isso um retrocesso. Primeiro faziamos tudo no codigo com numeros magicos. Depois foram movidos pra constantes. Depois extraiu-se as configuracoes relevantes para properties/XML/TXT/[qualquer coisa que nao seja compilado no codigo].

Nessa ultima etapa perdeu-se os recursos de verificacao em tempo de compilacao - mas a flexibilidade de poder alterar as configuracoes sem recompilar o codigo vale a pena na maioria dos casos.

Agora as anotacoes parecem querer trazer as coisas para o codigo, misturando configuracao e codigo e ainda perdendo a capacidade de deteccao de erros em tempo de compilacao (isso talvez seja contornavel).

Oras, o que eh de configuracao “complicada” (isso eh discutivel), como EJBs, Hibernate, etc, vai continuar sendo complicado, exceto se arrumarem um jeito “magico” de fazer a coisa - e esse jeito, IMHO, nao se resume a simplesmente mover as configuracoes de um lugar para outro. :smiley:

Eh isso ai - desculpem se nao entendi o “espirito” das anotacoes e viajei na maionese.

Marcio Kuchma

[quote=kuchma]Pode nao ter caido minha ficha ainda, mas acho isso um retrocesso. Primeiro faziamos tudo no codigo com numeros magicos. Depois foram movidos pra constantes. Depois extraiu-se as configuracoes relevantes para properties/XML/TXT/[qualquer coisa que nao seja compilado no codigo].

Nessa ultima etapa perdeu-se os recursos de verificacao em tempo de compilacao - mas a flexibilidade de poder alterar as configuracoes sem recompilar o codigo vale a pena na maioria dos casos.

Agora as anotacoes parecem querer trazer as coisas para o codigo, misturando configuracao e codigo e ainda perdendo a capacidade de deteccao de erros em tempo de compilacao (isso talvez seja contornavel).

Oras, o que eh de configuracao “complicada” (isso eh discutivel), como EJBs, Hibernate, etc, vai continuar sendo complicado, exceto se arrumarem um jeito “magico” de fazer a coisa - e esse jeito, IMHO, nao se resume a simplesmente mover as configuracoes de um lugar para outro. :smiley:

Eh isso ai - desculpem se nao entendi o “espirito” das anotacoes e viajei na maionese.

Marcio Kuchma[/quote]

A questão é que Anotações são menos verbosas que XML. Mas eu acho que seria muito melhor criar uma linguagem específica para fazer configurações. Groovy talvez seja a solução. Ou pelo menos ao invés de fazer assim:

  &lt;bla&gt; 
      &lt;ble&gt; abc &lt;/ble&gt;
  &lt;/bla&gt;

fazer algo assim…

  bla { 
      ble { abc }
  }

[quote=vamorim]

  &lt;bla&gt; 
      &lt;ble&gt; abc &lt;/ble&gt;
  &lt;/bla&gt;

fazer algo assim…

[code]
bla {
ble { abc }
}

[/code][/quote]

Para mim é a mesma coisa.

kuchma, dá para fazer verificações em tempo de compilação sim, quer dizer, de que possiveis verificações vc está falando? Bom, isso não me parece ser uma bronca. Mas concordo com o fato de que algumas configurações ficam melhor fora do codigo.

vamorim, criar uma linguagem parece menos coerente do que alterar a sintaxe das anotações, não? Outra linguagem é meio overkill.

valeuz…

[quote=danieldestro][quote=vamorim]

  &lt;bla&gt; 
      &lt;ble&gt; abc &lt;/ble&gt;
  &lt;/bla&gt;

fazer algo assim…

[code]
bla {
ble { abc }
}

[/code][/quote]

Para mim é a mesma coisa.[/quote]

Não reparou que o segundo é bem menos verboso?

Contando apenas os caracteres não-brancos temos 25 no primeiro e 13 no segundo. Ou seja uma economia de 50%.

Imagina a diferença em larga escala. Um arquivo XML de 1000 linhas por exemplo… Dá uma baita diferença na legibilidade…

Eu, o Vinci e um pessoal da PUC-RIo que esqueci infelizmente o nome tivemos uma conversa sobre isso na rodoviaria, voltando do STD.

Anotaçoes sao legais para MARCAR, nao para configurar. Por exemplo, voce deveria fazer algo assim (pseudocodigo):

@myTag
public japoneis(Zahl zahl){...}

E ter um outro lugar configurado que metodos marcados com @myTag sao logados, num XML, aspecto, properties, a la Mentawai ou qualquer outra coisa.

Agora fazer:

@log(trace=true)
public japoneis(Zahl zahl){...}

@log(trace=false)
public Zahl criaZahk(){...}

Cai no que o kuchma falou.

Complementando, annotations para mim sao como Serializable (tagging interfaces) feitos de maneira menos gambiarra :wink:

Nossa, que código engraçado. É Java? :twisted:

Falando sério, annotations são bem legais para aquilo que o Shoes falou. Fora isso, dá vontade de chorar :stuck_out_tongue:

Eu uso annotations nos meus posts :mrgreen:

@+ para indicar os editados como este :smiley:

@+ escroto

Sinceramente, acho um lixo encher o seu dao dessas anotações.

Gente, qual é o bixo de 7 cabeças em criar xml’s? E se é assim, por que não usar ferramentas que gerar o xml?

E como se os xmls do hibernate fossem tão complicados!

Erhm, não é nos DAO’s e sim nas classes de dominio! Eu gostei de anotações porque já estava bastante acostumado com XDoclet que, para novos sistemas, parece-me a abordagem mais apropriada. Claro que existem diferenças entre XDoclet e anotações, mas o proposito é o mesmo. Quanto a usar property access ao inves de field access, não acho que faça muita diferença não.

valeuz…

jack_-_ganzha,

ooops, não prestei muita atenção. Mas, de qualquer forma, não acho que anotações caiam bem para gerar os xmls do hibernate.

Bem, apenas uma opiniao…

Valeu!

Cara, aquela classe tem mais annotations do que código Java :lol:

Unghn! :shock:

a vantagem de anotações sobre XML é qu anotações são verificadas em tempo de compilação, e não só em runtime :smiley:

mas aquele é um exemplo extremo.

peguemos um exemplo do outro extremo:

@Entity(access=AccessType.FIELD) public class MyVo{ @Id(generate=GeneratorType.AUTO) private Integer id; private String nome; private .... }

Coloque quantos campos mais tu quiser, todos serão persistidos e tudo vai funcionar legaizinho :smiley:

agora faz isto com XML pra gente ver :twisted:

:D:D:D:D

mudando um pouco de assunto, eu tava usando as anotacoes do h3 sempre nos getters, nao nos atributos. ha alguma diferenca?

Polui o codigo sim, mas classes de modelo normalmente sao beans bem simples e que nao fazem muita coisa.

Mas eh muuuuito legal voce escrever @E e dar um control espaco! Pronto, classe hibernetada.

[quote=urubatan]a vantagem de anotações sobre XML é qu anotações são verificadas em tempo de compilação, e não só em runtime
[/quote]

No fundo, será que o problema não é das IDEs ?

Tanto annotations quanto os XMLs são usados para adicionar
metadados aos elementos da linguagem que serão usados em
determinado contexto.

Eu, particularmente, acho que as anotações, quando visualizadas da forma
atual, poluem o código. Acho que é aí o nó da questão.

Numa Dr. Dobbs +/- recente (acho que do ano passado), saiu um artigo de um cara advogando o uso do XML para o código fonte. Seu argumento: Qualquer equipe de desenvolvimento que quiser ter uma produtividade decente precisa de uma IDE. Todo mundo usa editores WYSIWYG, mas ninguem está precocupado como eles armazenam internamente (e no arquivo) a fonte utilizada em um parágrafo. Por que então deveríamos nos preocupar com isto no caso de código-fonte ? Quem determinou que, para toda existência, o fonte de um programa será texto-puro ? BTW, até o VB4 acho que ainda havia a opção de salvar o fonte em “formato binário”.

Tanto o XML quanto as anotações são pouco legíveis, encaremos este fato…

Imagino que a evolução natural das IDEs irá levá-las a ocultar as anotações, pelo menos na visão padrão do editor do fonte. O programador, clicando com o botão direito do mouse sobre um atributo ou usando um atalho, teria acesso a um diálogo amigável para preencher os metadados. Preencheu, fechou, pronto: de volta para um fonte limpo - pelo menos na aparência.

Para suportar isto, uma representação XML do fonte cai bem. Usando namespaces seria fácil suportar novas extensões e, em princípio, o próprio processo de compilação poderia expandido para incluir passos de verificação adicionais. Pex, no caso do Hibernate, um plugin para o compilador poderia acessar a base de dados e verificar se as tabelas criadas existem, se são compatíveis, etc.

[quote=psevestre]
Numa Dr. Dobbs +/- recente (acho que do ano passado), saiu um artigo de um cara advogando o uso do XML para o código fonte. [/quote]

esse?

[quote=AllMighty][quote=psevestre]
Numa Dr. Dobbs +/- recente (acho que do ano passado), saiu um artigo de um cara advogando o uso do XML para o código fonte. [/quote]

esse?[/quote]

Possivelmente. Ao menos a linha de argumentação é a mesma. Mas o artigo que li não era este, nem o da ACM.

A ideia era exagerar para deixar claro. No fim das contas, apenas remover todas as queries para um package-info já ajuda um bocado. Fora elas, não acho que o exemplo seja tão absurdo assim, especialmente quando for preciso usar outra anotações.

Prática acho que não. Eu comecei a usar nos fields porque nos primeiros releases havia alguns bugs bobos quando se usava nos getters.

valeuz…