Groovy: anotações poderosas!

Texto escrito em 2013

Groovy tem algumas anotações incrívelmente poderosas que vejo serem pouco faladas por aqui. O objetivo deste post é apresentá-las: como verão elas realmente não quebram galhos, mas troncos de sequóias!

Logging simples

Estas anotações provávelmente todos vocês já conhecem: são o suporte que a linguagem nos oferece para os mais variados frameworks de logging que a plataforma Java tem a nos oferecer.

  • @log - para o java.util.logging
  • @Commons - para o Apache Commons Logging
  • @Log4j - para o Log4j 1.x
  • @Slf4j - para o SLF4J
  • @Log4j2 - Para o Log4j 2.x (apenas a partir da versão 2.2 do Groovy)

O funcionamento é simples: anote sua classe com a anotação que representa o seu framework de logging favorito. Será injetado um novo atributo na sua classe chamado log que corresponde ao objeto Logger do seu framework. Em seguida, basta usá-lo exatamente com o faria no Java. Eis um exemplo:

import groovy.util.logging.*

@Log4j //pro caso do Log4J
class Brutality {
def metodo() {
// olha aqui o seu logger
log.info "Logando!"
}
}

O nome do logger por default equivale ao da classe. Quer customizá-lo? Fácil: basta passar uma string como valor para a anotação. Exemplo: @Log4j("logandoBruto") para um logger chamado logandoBruto. Depois basta configurar o seu framework da maneira que preferir.

Objetos imutáveis? Fácil também.

A anotação @Immutable do Groovy é aplicada sobre as classes cujos atributos não queremos que sejam alterados uma vez tendo sido definidos. Regra simples: sua classe deve ser do tipo final para que a regra se aplique. Como você faz? Simples: tal como no exemplo a seguir!

import groovy.transform.*
@Immutable
final class PessoaImutavel {
String nome
String sobrenome
}

Pronto: os setters gerados quando esta classe anotada são muito parecidos com o código a seguir:

void setNome(String valor) {
if (this.nome == null) {this.nome = valor;}
}

Cacheando métodos com @Memoized (Groovy 2.2)

Uma novidade bacana no Groovy 2.2: a anotação @Memoized. O que ela faz é cachear o resultado da invocação de uma função. Deve ser aplicada naqueles seus métodos cujo resultado sempre é o mesmo para um dado conjunto de argumentos, ou seja, as funções que não dependem de efeitos colaterais.

Use com cuidado este recurso: aplique-o somente em funções que sempre retornam o mesmo valor para um dado conjunto de parâmetros. Abaixo está um exemplo da sua aplicação:

import groovy.transform.*

class IntegratorTabajara {

@Memoized
double calculoBruto(double parametro) {

// após longo cálculo retorna o valor
}

}

Após a primeira invocação, caso o parâmetro seja o mesmo, será retornado apenas o valor computado para aquele valor. Isto aumenta muito a performance do seu sistema quando bem aplicado (quando bem aplicado).

Representação em forma de string de forma fácil com @ToString

Pra finalizar uma anotação que vai te poupar muito tempo. Você sabe aqueles momentos em que fica escrevendo aquela função toString para retornar uma representação dos seus objetos (especialmente em Grails quando queremos expô-los de uma forma bacaninha nos combos)? Há uma anotação que faz este trabalho pra você.

De novo, é simples: basta anotar sua classe com @ToString como no exemplo abaixo:

import groovy.transform.*
@ToString
class Pessoa {
String nome
String sobrenome
}

println new Pessoa(nome:"Henrique", sobrenome:"Lobo")
// saida formatada:
// Pessoa(Henrique, Lobo)

Mais simples impossível: poupa muito tempo. :)

Concluindo

Notou que em diversos exemplos importo o pacote groovy.transform? Todas estas anotações são baseadas no recurso AST (Abstract Syntax Tree) Transformations do Groovy, que nos permite alterar o processo de compilação do código. Um recurso muito interessante sobre o qual pretendo escrever em muito breve. ;)

Ah, e poupe seu tempo com estas anotações ok?

22