Relato FSLDC 2013 + saiba como iniciar com Grails!!

Salve Groovy Coders,

No dia 20/07/2013 tive a oportunidade de palestrar no V Fórum de Software Livre de Duque de Caxias.

fsldc2013

O foco da minha apresentação era mostrar como é fácil aprender a usar o Grails. Para quem ainda não conhece, a apresentação utilizada está disponível online no Heroku e o seu código fonte está no meu github, lembrando que esta apresentação foi feita utilizando o Reveal.js dentro de uma aplicação Grails. Ou seja, até a apresentação foi feita com Grails.

Um dos itens mais interessantes deste dia foi que eu convidei uma das pessoas que estavam assistindo a palestra para criar um projeto do zero, isso no esquema Piloto e Copiloto (Lembrando que eu era apenas o copiloto). O Jogador do dia foi o Douglas Lemos. Que por sua vez criou um projeto do zero, ao vivo e sem IDE (Apenas o Terminal e o VIM) sem nunca ter nem ouvido falar de Grails antes da palestra. Às vezes eu acho que ele teve mais facilidade com o framework do que com o VIM.

Alguns dias depois, recebi alguns emails de pessoas que queria começar a estudar Grails, pedindo indicações de livros, apostilas e links. Logo tive a ideia de escrever esse post com a minha opinião sobre qual é o melhor caminho para começar neste novo mundo, pois intendo que esta dúvida pode ser a de outros Devs também.

Lembrando que essa é apenas uma opinião pessoal. Aqui tem o que eu considero importante por ter dado certo comigo.

 

grails

Como iniciar com Grails?

Primeiro e mandatório: Faça exemplos, escreva, erre, isso fará com que você evolua;

Livros:

Para aqueles que gostam de uma boa literatura, algo que te leve do básico ao avançado respeitando todo um fluxo natural da linguagem eu indico dois livros:

1 – Grails in Action: Para mim o official deste framework.

2 – Groovy in Action: Sobre a linguagem por de traz do Grails. Escrito pelo próprio criador da linguagem.

Sites:

1 – O próprio site da aplicação, já com uma série de tutoriais e exemplos.

2 – Grails.io, que é o blog oficial do criador do framework Graeme Rocher.

3 – Glaforge, que é o blog oficial do criador da linguagem por de traz do Grails, o Groovy.

4 – DevKiko, este é o site do Henrique Lobo, referência Grails no Brasil.

5 – SantoGrails o próprio. Que está descrito aqui não por ser melhor do que os demais e sim por ser escrito por um iniciante que sou eu. A idéia é descrever uma linha de raciocínio na linguagem dos iniciantes.

Tutoriais:

1 – O oficial.

2 – Instalando e configurando o Grails.

3 – Criando minha primeira aplicação Grails

4 – Boas Praticas com Grails. Este é muito importante, pois seguir as dicas descritas neste post evita uma série de erros que acabam com a vida de qualquer iniciante.

Comunidade:

Algo muito importante é ter acesso ou de preferência conhecer pessoas envolvidas com o framework e nada melhor do que as listas para conhecer esses caras.

1 – O próprio site do Grails tem uma lista das comunidade de Grails.

2 – No linkedin tem uma galera muito ativa.

3 – Grupo de Devs Grails no Brasil.

4 – GrailsRio, criada para juntar a galera de Grails do Rio de Janeiro.

Por fim, sei que talvez isso não tenha muito a ver, mas de preferência criem seus códigos usando o GIT. Caso ainda não conheçam façam este treinamento free online de apenas 15 minutos. Vale muito a pena.

Após ter sua conta no Github, porque não dar um fork no projeto do Grails?

Espero ter ajudado e caso alguém conheça mais itens que podem ajudar no estudo, comentem, pois, além de eu responder posso atualizar o post.

Até a próxima e bons estudos.

Reutilização com Grails Validators

Salve Groovistas!!

É sempre bom descobrir recursos que podem tornar o nosso código mais reutilizável.
Logo, hoje focaremos nos famosos validators do grails.

Sabemos que todas as classes que implementam o @Validatable possuem uma closure estática de nome constraints que pode empacotar algumas regras comumente ligadas ao domínio em questão, facilitando muito na hora de verificar a integridade dessas informações antes de tentar persistir o mesmo.

Depois de muito tempo criando e alterando constraints, eu comecei a ficar incomodado com tanta repetição de código e decidi averiguar a possibilidade de tornar o meu código um pouco mais reutilizável. Foi ai que encontrei três maneiras de reutilizar os validadores do grails.

Podemos separar os validadores reutilizáveis em três categorias:
Empacotados
Globais
Formulário de CommandObject

1 – Empacotados:
Neste caso não é preciso muito conhecimento em grails, pois estamos apenas utilizando orientação a objetos.

Onde pegamos o que se repete e separamos em uma classe, sendo que a única novidade é a maneira que chamamos esse código.

// É sempre bom descobrir recursos que podem tornar nosso projeto mais reutilizável.
class Validators {

    static final confirmPasswordValidator = { value, command ->
        if (command.password != command.confirmPassword) {
            return 'command.confirmPassword.error.mismatch'
        }
    }

    static def requiresAtleastOne =  {val, obj->
        if(!val?.size()){
            return "default.requires.atleast.one"
        }
    }
}
class MyDomain {
        static constraints = {
              items(validator: requiresAtleastOne)
        }
}

Primeiro criamos a classe que ira empacotar as nossas validações, para logo em seguida criar as nossas validações como closures estáticas com seus parâmetros de entrada, lógica de verificação e mensagem de erro para o retorno caso seja necessário.
Para que essa classe seja utilizada como validação, precisamos apenas chama-la de dentro da constraints de nossa classe em questão seguindo a seguinte convenção <atributo_da_classe_local>(<classe_de_validacao>:<closure_de_validacao>). Simples assim.

2 – Globais:
Também podemos reaproveitar nossas validações utilizando o “Global Constraints”
Este é um recurso que precisa ser configurado de dentro do grails-app/conf/Config.groovy. Definindo validações genéricas que serão seguidas por todos os nossos domínios.

//Tambem podemos reaproveitar nossas validações com o "Global Constraints ".

//Podemos aplicar este recurso de dentro do grails-app/conf/Config.groovy
//Definindo validações para todos os domínios
grails.gorm.default.constraints = {
    '*'(nullable: true, size: 1..20)
}

// Ou até até criando diferentes validações globais
grails.gorm.default.constraints = {
    myShared(nullable: true, size: 1..20)
}

//Que pode ser chamadas da seguinte forma
class User {
    static constraints = {
        login(shared: "myShared")
    }
}

3 – Formulário de CommandObject:
Por último, temos o importForm muito utilizado em projetos que seguem o conceito de command object.

Neste caso temos duas classes de cara, o nosso domínio e o seu respectivo Command Object. Praticamente replicamos o constraints do Domain no Command Object, mas seus problemas acabaram!!!!

Com o importForm, no lugar de reescrevermos todas as validações do Domain, nós precisamos apenas escrever importForm . Mais simples impossível!

Segue um exemplo mostrando sua utilização e praticidade:

//Outro recurso que chamou bastante minha atenção foi o importForm.
//Este é um recurso muito utilizado para replicar as validações do domínio para o seu command object.

//Digamos que em nosso projeto tenhamos o seguinte domínio:
class User {
    String firstName
    String lastName
    String passwordHash
    static constraints = {
        firstName blank: false, nullable: false
        lastName blank: false, nullable: false
        passwordHash blank: false, nullable: false
    }
}

//Podemos com o importForm replicar as validações do domínio para o nosso command:
class UserCommand {
    String firstName
    String lastName
    String password
    String confirmPassword
    static constraints = {
        importFrom User

        password blank: false, nullable: false
        confirmPassword blank: false, nullable: false
    }
}

Se você conhece outra maneira de reaproveitar seus validadores não deixe de compartilhar. Comente no post.

Transformando métodos complexos em closures

Salve Groovystas,

Peço desculpas pelo tempo sem posts. Espero que isso não se repita… pois tenho bastante coisa para escrever e com isso pretendo criar a rotina de postar semanalmente.

Em alguns momentos nos deparamos com métodos que devido sua complexidade são difíceis de refatorar.
Recentemente, passei pelo seguinte problema de desempenho:
No sistema existe um método complexo que precisava ser chamado de dentro de um loop e isso sobrecarregava o processamento da funcionalidade em questão.
Devido à urgência desta tarefa, o melhor recurso encontrado neste momento foi a utilização do “memoize()”.
Este é um resumo sobre memoize para facilitar o entendimento:

//Problema: Quando temos um loop e dentro dele temos uma determinada
//lógica que precisará ser executada em todas as iterações;
(1..10).each{println  "este numero é ${it+5*(10-1)}"}

//Solução: Podemos otimizar nosso código inserindo nossa lógica dentro
//de uma closure, onde ao final desta chamamos o método memoize().
c = {println "este numero é ${it+5*(10-1)}"}.memoize()

//Por fim, chamamos esta closure de dentro do loop para que apenas a primeira
//interação seja 100% processada, pois nas próximas a parte repetida desta
//logica ficará em cache apenas sofrendo alteração de parâmetro.
(1..10).each(c)

Esse foi apenas um resumo, um exemplo rápido para não jogarmos termos novos sem explicação no post, mas em breve pretendo escrever exclusivamente sobre esse recurso que já me salvou varias vezes.

Mas, para nossa infelicidade, esta complexidade estava dentro de um método. Logo este precisou virar uma closure.

Imagine que estamos lidando com um método que é frequentemente alterado, como um cálculo de tarifa ou algo parecido e que é chamado por varias outras classes. Nesta situação, se alterássemos este método para uma closure, isso implicaria em um preenchimento desnecessário da PermGem, sem contar que iriamos inserir o memoize(), que seria um recurso desnecessário para a maioria dos casos. Logo estaríamos concertando de um lado para provavelmente estragar de outro.

Chega de revira volta!!! Vamos para o Show me the code!

Neste caso podemos utilizar “reference.&”, que recupera toda a lógica de um determinado método e a transforma em uma closure.

class SizeFilter {
    Integer limit
    boolean filter (String value) {
        return value.length() <= limit
    }
}

SizeFilter six = new SizeFilter(limit:6) //#1 Construtor

SizeFilter five = new SizeFilter(limit:5) //#1 Chamada

Closure smallerSix = six.&filter //#2 Associando o método à closure

def words = ['long string', 'medium', 'short', 'tiny']

assert 'medium' == words.find (smallerSix) //#3 Chamando a closure

assert 'short' == words.find (five.&filter) //#4 Passando a closure diretamente

Lembrando que os recursos fornecidos, raramente são para todas as situações. Logo, nada como uma boa análise antes de sairmos codificando.

Por fim, algo que chamou muito minha atenção, foi o fato de o “reference.&” também trabalhar em cima do polimorfismo conforme exemplo abaixo:

class MultiMethodSample{
    int mysterMethod(String value){
        return value.length()
    }
    int mysterMethod(List list){
        return list.size()
    }
    int mysterMethod(int x, int y){
        return x+y
    }
}

MultiMethodSample instance = new MultiMethodSample()
Closure multi = instance.&mysterMethod

assert 10 == multi ('string arg')
assert 3  == multi (['list', 'of', 'values'])
assert 14 == multi (6, 8)

Como podemos notar, o processamento da closure muda quando alteramos os parâmetros.

Espero ter ajudado com a dica e até os próximos posts.

O Nirvana da Programação parte 2 – Montando meu ecossistema social:

PodCasts de Tecnologia: GrokPodCast e CastalioPodCast

Definição: Audios disponíveis para ouvir online ou baixar sobre tecnologia.

Detalhes: As vezes quando não temos tempo para uma boa leitura ou não conseguimos ler muito bem no ônibus, podemos optar por ouvir o mesmo conteudo.

Aqui eu estou listando dois podcasts que realmente deram a uma cara nova ao meu ecossistema tecnológico!

Temos o CastalioPodCast(http://www.castalio.info ) voltado para tecnologia em geral e o GrokPodCast(http://www.grokpodcast.com/) completamente voltado para desenvolvedores!! É impressionante a quantidade de coisas que eu já aprendi só ouvindo estes podcasts indo para o trabalho e se você esta na mesma situação que eu (transito louco do Rio de Janeiro) você leva bastante tempo dentro do ônibus! Rsrs!

Dojo de programação

Definição: Local para treinamento de desenvolvedores ninjas!

Detalhes: Em um dojo, aprendemos a de fato entender o problema antes de sair codando, praticamos trabalho em grupo, TDD e fazemos um network de causar inveja em algumas pessoas que ficam curtindo o mundo pela janela de casa!

CodeSchool

Denifição: site com cursos online completamente voltados para programação que seguem a seguinte filosofia, aprender fazendo! E ainda não vi curso melhor dentro dessa categoria!

Detalhes:  Apesar de termos poucos cursos disponíveis de graça, os pagos são baratos, rápidos e intuitivos. Eu tenho a impressão de que ele faz até quem não gosta de programação gostar.

Network

Definição: Todo bom programador não é bom programador sozinho, estamos em um ecossistema rico de seres vivos cheio de conhecimento para disseminar e não podemos nos trancar em uma bolha, precisamos sim nos envolver e muito!

Detalhes:

Dojos e programação – Estou citando novamente este cara porque os melhores desenvolvedores que conheço fazem parte de algum grupo de dojo.

Eventos de TI: Temos que nos localizar… e nada melhor que escolher o mundo que queremos fazer parte após conhecer a galera que esta nele! Ex: Podemos ir a um evento de Python e ver como rola o network ou podemos ir a um evento de Ruby e assim por diante. O importante é tentar ficar por dentro.

GeeksOnBeer: Este é um evento que ocorre todo mês e tem como objetivo reunir programadores com espirito empreendedor com os caras que podem financiar o seu projeto. Fala sério!!… Qual programador não quer tirar uma onde de Mark Zuckerberg!

Inglês

Definição: Não preciso nem falar o quanto ele é importante em nosso cinto de utilidades.

Detalhes: Muitos podem estar esperando ter condições para poder entrar em um curso de inglês, mas isso não e completamente necessário existe recursos web que para alguns ajudam até mais que cursos e não estou falando de cursos online, estou falando de aplicativos como se fossem redes sociais voltadas para quem quer aprender outra língua. Ex: LiveMocha (http://livemocha.com/). Aqui você além de aprender inglês interagindo faz amigos fora do Brasil.

Motivação e Internet disponível

Não adianta ter todos esses aparatos se não existir muita motivação e vontade de aprender!

Por fim, não tenha vergonha de entrar em contato. Grande parte dos ícones do mundo tecnológico que conhecemos tem uma disposição muito grande em contribuir com conhecimento.

Certamente existem outros itens de grande valor, mas o intuito foi tentar traças um norte.

Espero ter ajudado!

Referências:

Linkedin            : http://linkedin.com/

Git                 : http://git-scm.com/

Github              : http://github.com/

Heroku              : http://heroku.com/

Appengine           : http://developers.google.com/appengine/

CastalioPodCast     : http://www.castalio.info/

GrokPodCast         : http://grokpodcast.com/

Dojo de programação : http://dojorio.org/

CodeSchool          : http://codeschool.com/

Geeksonbeer         : http://geeksonbeer.com/

Livemocha           : http://livemocha.com/

O nirvana do programador parte 1 – Montando o meu portfólio:

Salve Groovistas e Grailsnaltas de plantão!!

Dessa vez vou fugir um pouquinho de groovy e grails para passa um pouco do que eu considero de extrema importância para todo o programador que se preze!
Tudo começou quando eu comecei na empresa que estou atualmente a alguns meses. Aqui, pude perceber que a maioria dos desenvolvedores não possuem uma conta no Github, alguns nem sabiam do que se tratava!!!
A um tempo atraz eu montei uma apresentação de grails para o openspace e hospedei ele no heroku. Apenas um dos que entrei em contato conhecia  heroku! Nem heroku, nem AppEngine da Google.
Não sei se isso é fase, mas estou em uma “vibe” completamente open source, sinto uma necessidade absurda de disseminar este tipo de informação. Fico inquieto ao saber que um programador nunca ouviu falar no Git ou afins.
Por causa disso eu decidi postar uma espécie de receita de bolo para programadores da geração Y ou atual… Que seja… Para aqueles que querem estar por dentro do que temos de recursos altamente voltados para melhorar o nosso ecossistema de desenvolvedor!
Pois bem… Eu estava pesando em fazer um post rápido, apenas com alguns links e dicas, mais deu três páginas. Logo decidi separar este artigo em dois posts.

  • O nirvana do programador parte 1 – Montando o meu portfólio: Linkedin, Git, Github, Heroku e Appengine.
  • O nirvana do programador parte 2 – Montando meu ecossistema social: Dojo de programação, network, codeschool, inglês, motivação e internet disponível.

Linkedin

Definição: Rede social voltada para profissionais.
Detalhes: Insira todos os seus dados profissionais (relevantes é claro rsrs), pois ele funciona como um currículo online, mas ele é mais do que isso! Siga as empresas que você considera importante, faça parte de grupos que tem relação com o seu objetivo profissional e se junte a pessoas que possam te ajudar a construir uma rede profissional valiosa. Lembre-se que muitas empresas de RH utilizam o linkedin para procurar profissionais.

Git e GitHub

Definição: Git é o controlador de versão criado pelo Linus Torvalds para manter o código fonte do Kernel do Linux e Github é um repositório online, o mais utilizado no mundo para projetos open source.
Detalhes: Não existe currículo melhor para um programador que o seu Github. Nele, você pode incluir todos os seus projetos para que outras pessoas possam ver como você trabalha e até contribuir com o código de outros. Muitas empresas de nome forte no mercado utilizam o Github e aceita alterações enviadas pela comunidade com bem menos burocracia que os repositórios tradicionais (Rails, Grails e outras ferramentas de grande importância para o nosso ecossistema estão lá disponíveis para ser baixados).

Heroku e Appengine

Definição: Serviços de hospedagem de aplicação.
Detalhes: Quer fazer deploy para a nuvem para que outras pessoas saibam o que você fez? Você precisa conhecer o Heroku ou o AppEngine.
Com estes serviços o desenvolvedor é capaz de deixar suas aplicações funcionando na web até sem pagar nada! Prova disso é a apresentação de grails que eu montei (http://apresentacaograils.heroku.com) não estou pagando nada por ela ,utilizando o seu subdomínio … É claro!
No momento estou utilizando o Heroku pelo sua integração quase que nativa com o git rsrs!

Por hoje é só pessoal, mas já já eu posto a continuação deste artigo

Dojo na Praça do Conhecimento

Salve Groovistas!

Desta vez este post é para falar de como foi o primeiro de muitos dojos na praça do conhecimento, uma entidade filantrópica que tem como objetivo trazer a tecnologia para a rotina das crianças do Alemão.

Faço parte da lista do dojorio onde o Felipe Melo, uns dos professores do local, postou um convite para elaborar um dojo na praça do conhecimento. Como neste dia a minha tarde de sábado estava livre, pude aproveitar e ir ajudar a galera do dojo.

Aventura

Para mim, foi uma super nova experiência, pois foi a primeira vez que eu entrei em uma comunidade sozinho e o mais legal é que toda aquela impressão que eu tinha foi quebrada até pela recepção das pessoas que me ajudaram a chegar à praça do conhecimento, que por sinal possui uma super infraestrutura de ensino. Fiquei muito feliz em ver iniciativas deste nível acontecendo em uma comunidade e dando certo. Crianças com acesso a internet, cursos voltados para tecnologia e agora dojo de programação rsrs!

Devido alguns contratempos, não foi possível a presença daqueles que de fato sabem configurar um ambiente para dojo (Lembrando que eu só frequento dojos, nunca criei nem preparei o ambiente de um).

Preparar o ambiente para o dojo foi a segunda parte da aventura!

Infraestrutura

Comecei este processo mostrando a galera presente, o github, já que a primeira coisa que me veio em mente foi baixar o DojoTimer – ( Quem disse que eu consegui botar a bagaça para funcionar rsrs). Durante este overview pelo GitHub, pude apresentar a filosofia de programar não só por dinheiro, mas , mais ainda por uma realização pessoal e ser colaborativo que é a filosofia de desenvolvimento que eu acredito ser a correta.

Apresentei o GitHub, mas não consegui configurar o DojoTimer, onde para minha supresa, um dos presente sugeriu ver um projeto pronto para entender como o teste estava sendo executado. Tai!!! Eu aprendi junto com os caras como funcionava o teste unitário do python seguindo o fizzbuzz feito no meu primeiro dojo na globo (ainda bem que o código tinha sido postado no github).

Mudando o Planejamento

No meio da explicação do FizzBuzz um dos presente perguntou, “para que isso serve”! Essa pergunta me fez pensar no padrão falido de ensino que temos e que eu estava indo no mesmo caminho. Naquele lugar eu não estava lidando com programadores e alguns nem sabiam se gostariam de ser programadores! Lembrei na mesma hora da pesquisa do Carlos Flores sobre ensino, onde o primeiro passo é criar um produto! Foi exatamente isso o que iriamos fazer, algo que eles gostaria de ver funcionando.

Grails

Apesar de eu ser um fã de python eu me considero um evangelista grails, e não pude perder a oportunidade.  Para mostrar como grails é simples um dos presentes foi chamado para preparar o ambiente para grails e criar o projeto.

O voluntário a programador foi o Grande Lucas! Que fez tudo corretamente, o problema foi minha falta de conhecimento, onde após o projeto pronto não foi possível criar o CRUD devido a falta do jar do hibernate, que eu não consegui identificar o real motivo!!!

Conteúdo Nerd Total

Como o ambiente que eu criei estava furado! Rsrs! Mostrei uma apresentação do grails que eu tinha montado para o OpenSpace e a galera curtiu bastante!  Até um coordenador presente acho o grails simples!!

Após uma apresentação desse tipo, nada como um papo descontraído sobre como funciona a rotina de um desenvolvedor e foi disso que o nosso dia foi preenchido!! Foi basicamente um intensivo de oque um programador deve conhecer.

Falamos sobre: Git, Github, Heroku, Linux, Ubuntu, Python, aplicações científicas, biotecnologia, GrokPodCast e NerdCast. Para mim foi a melhor parte do dia!!

Por fim, participar deste tipo de evento não tem preço, principalmente quando você contribui diretamente!

Programação semântica com Groovy: FizzBuzz

Salve Groovistas!!

Ontem pude participar do DojoRio na Íparos e hoje estava relembrando do meu primeiro Coding Dojo!

O primeiro Coding Dojo … agente nunca esquece. O problema selecionado foi o do FizzBuzz, que para quem não sabe é criar um algorítimo que ao receber qualquer número pode assumir três retornos:

  • Se for múltiplo de 3 – Retorna “fizz”
  • Se for múltiplo de 5 – Retorna “buzz”
  • Se for múltiplo de 3 e 5 ao mesmo tempo, deve retornar “fizzbuzz”

Na época o algorítimo foi implementado em python, mas atualmente estou programando em Groovy, decidi refazer o algorítimo, porém com Groovy.

O cógido ficou mais ou menos assim:

fizzbuzz = {it%3==0 & it%5==0 ? 'fizzbuzz' : it%3 == 0 ? 'fizz' : it%5==0 ? 'buzz' : 'Without fizzbuzz!'}

Um programador pode até entender mais para aumentar a coesão, podemos fazer o seguinte:

seMultiploDeCinco = {it%5==0};seMultiploDeTres = {it%3==0}
fizzbuzz = {seMultiploDeTres (it) & seMultiploDeCinco (it) ? 'fizzbuzz':
             seMultiploDeTres (it) ? 'fizz':
             seMultiploDeCinco (it) ? 'buzz':
             'Without fizzbuzz!'}

Neste caso encapsulamos as regras que se repetem e demos um nome fácil de abstrair e em seguida chamamos os mesmos.

Sem querer mudar muito de assunto, mas se atendo mais ao título. Precisamos nos atentar para a clareza de nosso código, precisamos nos esforçar para deixa-lo claro e manutenível.

Hoje com o movimento Agile – Percebemos que as vezes não temos tempos para a documentação tradicional e é nessas horas que o nosso código deve ser auto documentável.

Lembrando que não estou falando só dos comentários que devem ser claras abstrações do negócio, mas também da forma que escrevemos o código. Podemos notar que da maneira que o fizzbuzz foi refatorado, não existe a necessidade de comentar os métodos devido a clareza de seus nomes.

Por fim, devemos tratar nossos códigos como as mães tratam seus filhos, mantendo-os limpos ao máximo para evitar que falem mal deles ou de como cuidamos deles!!

 

Por: Jonatas Emidio.

Apresentação Grails com HTML5 no Reveal.js

Produtividade ao extremo na JVM com Grails!!

Segue link da apresentação montada para montral como ficou muito mais facil trabalhar na Web com Grails.

Apresentação Grails: apresentacaograils.herokuapp.com

Método X Closure: Melhorando o desempenho da aplicação – Parte 3

Salve Groovy Geeks de plantão!

Chegamos ao final dessa jornada sobre métodos e closures groovy.

Pois bem, reta final apenas para essa serie dividida em três episódios, lembrando que nada nos impede de fazer como os Simpson e dar continuidade em outras temporadas.

Nos últimos artigos vimos como as closures podem ser uteis no dia a dia do desenvolvedor groovy. Porém, o foco deste post em questão é trazer a tona detalhes não tão claros sobre o mundo das closures, nos levando a uma análise um pouco mais profunda antes de substituirmos métodos por closures.

Para começar temos um exemplo de um calculo de soma simples, feito no eclipse com o plugin do groovy, onde o JUnit forneceu as métricas.

Exemplo 1

Comparação Metodo X Closure em cálculos matemáticos:

public class PerfmTests {

	@Test
	public void testMetodos() {
		MetClos mc = new MetClos()
		1000.times{
		mc.m1()
		// depois com
		// mc.m2(10,20)
		}
		Assert.assertNotNull('')
	}

	@Test
	public void testClosures() {
		MetClos mc = new MetClos()
		1000.times{
		mc.c1()
		// depois com
		// mc.c2(10,20)
		}
		Assert.assertNotNull('')
	}

}

class MetClos {
	def c1 = {
		def s = 1 + 1
		println s
	}

	def c2 = { n1,n2 ->
		def s = n1 + n2
		println s
	}

	void m1() {
		def s = 1 + 1
		println s
	}

	void m2(n1,n2) {
		def s = n1 + n2
		println s
	}
}

Neste exemplo os testes com closures foram cerca de 10x mais rápidos que os métodos.

Cuidado

Um ponto negativo de trocar todos os métodos por closures é que cada closure vira um .class distinto e isso pode inchar bastante o perm space da JVM.

Exemplo 2

Comparação Método X Closure em comparações de elementos:

def numberCount = 10000
def random = new Random()
def unorderedList1 = (1..numberCount).collect{random.nextInt()}
def unorderedList2 = (1..numberCount).collect{random.nextInt()}

def timeit = {String message, Closure cl->
    def startTime = System.currentTimeMillis()
    cl()
    def deltaTime = System.currentTimeMillis() - startTime
    println "$message: \ttime: $deltaTime"
}

timeit("compare using closure") {
    def comparator= [ compare: { a,b -> return b <=> a }] as Comparator
    unorderedList1.sort(comparator)
}

timeit("compare using method") {
    Comparator comparator = new MyComparator()
    unorderedList2.sort(comparator)
}

class MyComparator implements Comparator {
    int compare(a, b) {return b <=> a}
}

Neste caso, temos exatamente o contrário. O desempenho da closure foi bem abaixo do esperado.

Para o algoritimo descrito as closures levaram 270ms diante dos métodos que levaram 50ms.

Exemplo 3

Melhorando o desempenho das closures em loops:

Pois bem… Um recurso muito interessante e que pode nos proporcionar o ganho considerável de desempenho, claro quando utilizado com sabedoria, é o groovy .memoize().

Este recurso está disponível a partir do groovy 1.8+.

Explicação do exemplo a seguir

Suponha uma função “distance” que calcula a distância entre dois pontos.

Closure distance tradicional:

def distance = {x1, y1, x2, y2 ->
    sleep(200)  //just to add a delay for demo purposes
    Math.sqrt((x2 - x1)**2 + (y2 - y1)**2)
}

Chamada 5 vezes utilizando uma closure tradicional:

5.times {
    def t1 = System.currentTimeMillis()
    println distance(100, 20, 400, 10)
    println "took: ${System.currentTimeMillis() - t1} milliseconds to execute"
 }
[/sourcecode ]
Após executarmos este trecho de código teremos a seguinte saída:

1
300.1666203960727
took: 201 milliseconds to execute
300.1666203960727
took: 200 milliseconds to execute
300.1666203960727
took: 201 milliseconds to execute
300.1666203960727
took: 201 milliseconds to execute
300.1666203960727
took: 201 milliseconds to execute
[/sourcecode ]

Sempre que chamamos a closure todos seus itens são chamados novamente, exigindo reprocessamento.

Vamos fazer o mesmo, porém utilizando o <em>memoize</em>
1
def distance = {x1, y1, x2, y2 ->
    sleep(200)  //just to add a delay for demo purposes
    Math.sqrt((x2 - x1)**2 + (y2 - y1)**2)
}.memoize() //Note now closure is memoized

//To Call It 5 Times
5.times {
    def t1 = System.currentTimeMillis()
    println distance(100, 20, 400, 10)
    println "took: ${System.currentTimeMillis() - t1}"
}

Após executar o código utilizando o memoize temos o seguinte resultado:

300.1666203960727
took: 202 milliseconds to execute
300.1666203960727
took: 1 milliseconds to execute
300.1666203960727
took: 1 milliseconds to execute
300.1666203960727
took: 0 milliseconds to execute
300.1666203960727
took: 0 milliseconds to execute

Pronto! Vemos claramente o quanto podemos ganhar desempenho conhecendo os recursos oferecidos pela linguagem.

Gostaria de salientar que, devemos tomar cuidado para não julgar precipitadamente o que é melhor, levando em consideração que desempenho também tem haver com a forma implementada e recursos oferecidos pelas linguagens.

Como dito anteriormente, estes três posts foram baseados nas respostas postadas no fórum do grails Brasil. Logo, gostaria de agradecer aqueles que contribuíram diretamente para a finalização deste post:

  • José Yoshiriro: Exemplo 1;
  • Raphael Miranda: Observação 1;
  • Pedro Henrique: Exemplo 2,  Exemplo 3;
  • Henrique Lobo Weissmann e Raphael Miranda: Considerações.

Gostaria também de agradecer aqueles que contribuíram indiretamente, os responsáveis pelo conteúdo dos links utilizados no fórum:

  • Michael Pollmeier:  closures significantly slower than methods?
  • Kushal Likhi: memoize sample

Segue links utilizados:

Por: Jonatas Emidio

Método X Closure: Isso o método não faz – Parte 2

Agora que já conhecemos o funcionamento básico das closures e vimos que elas podem ser entendidas como métodos, não porque são as mesmas coisas e sim pelo fato de as closures encapsularem também as características de um método.

Veremos neste post, em detalhes, qual a real diferença das closures com os métodos.

Devemos tomar muito cuidado ao utilizar as closures, diferente dos seus primos métodos, cada closure criada se transforma em um .class e ninguém quer deixar a memória da JVM de barriga cheia sem necessidade.

Voltando ao mundo de desenvolvimento ágil…
O simples fato de poder não declarar parâmetros quando só existe um já é um ponto positivo. “Em minha opinião, é claro!”.

As funcionalidades quadrado a seguir fazem a mesma coisa:

public int quadrado(int a){
    return a**2;
}

quadrado = { it**2 }

Como vimos no post anterior, a closure é um bloco de código encapsulado em um objeto e esta lógica pode até ser passada por parâmetro.

Um dos meus exemplos favoritos do groovy in action é a transformação de uma função em closure para poder ter sua lógica passada por parâmetro.

class MethodClosureSample{
    int limit
    MethodClosureSample(int limit){
        this.limit = limit
    }
    boolean validate(String value){
    return value.length() <= limit
    }
}

MethodClosureSample first = new MethodClosureSample(6)

// recurso ‘.&’ retornara não o valor mas a lógica contida no método
Closure firstClosure = first.&validate

def words = ['long string', 'medium', 'short', 'tiny']

println words.find(firstClosure) //Imprime:  medium

Definição:
MethodClosureSample: É uma classe que por definição recebe em seu construtor um numero que será utilizado para validar em um determinado método.

validate: É um método que recebe uma String e verifica se o tamanho da mesma é menor ou igual ao valor informado na criação do MethodClosureSample.

Instanciamos a MethodClosureSample.

Agora que vem a mágica. Utilizamos o “.&” para no lugar de executar o método e retornar o seu valor, nós retornamos a lógica atribuída a este método.

Criamos a closure firstClosure  que nada mais é que a lógica do validate da classe first.

Agora que temos a nossa closure que começaremos a diversão:

Começamos criando uma lista de palavras e em seguida chamando dessa lista a closure find (find – é uma closure que recebe outra que retorne boolean por parâmetro iterando na lista e retornando o 1º elemento true de acordo com a closure parâmetro).

println words.find(firstClosure) // que por sua vez retorna:  ‘medium’

Pronto: Aqui nós temos o find iterando a lista e verificando o resultado da atribuição do item iterado a closure parâmetro.

Por fim. Já sabemos o que é closure e conhecemos alguns de seus recursos que se encontram fora do escopo dos métodos tradicionais.

No próximo post veremos alguns testes de desempenho e seus resultados, sem falar em como melhorar o desempenho das closures em loops.

Post anterior: http://santograils.wordpress.com/2012/07/20/metodo-x-closure-entendendo-as-closures-no-groovy-parte-1/

Por: Jonatas Emidio

Seguir

Obtenha todo post novo entregue na sua caixa de entrada.