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.

Anúncios

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.

grailstalk

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:


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>

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: https://santograils.wordpress.com/2012/07/20/metodo-x-closure-entendendo-as-closures-no-groovy-parte-1/

Por: Jonatas Emidio

Método X Closure: Entendendo as Closures no Groovy – Parte 1

Uma das coisas que mais tem me chamado a atenção no groovy é o seu suporte à closures. Logo passei a utiliza-las no lugar dos métodos, já que a principio a função era a mesma. No entanto me surgiu uma dúvida… Será que eu ganho ou perco desempenho utilizando-as na aplicação?
Iniciei as consultas no google e não tive muito sucesso, em seguida postei minha duvida no grails brasil e pouco depois já tinham várias respostas. Percebi que o conteúdo que estava sendo gerado era muito rico e tive a ideia de compilar todas essas informações em um post de fácil entendimento.
Pois bem, para começar “métodos e closures” podem até trazer o mesmo resultado, mas eles não são a mesma coisa.
Este artigo será dividido em 3 posts, pois o mesmo possui bastante conteúdo.

  1. Entendendo as Closures no Groovy;
  2. Método X Closure;
  3. Teste de desempenho com Closures e Métodos;

Entendendo as Closures no Groovy

Segundo o Livro Groovy in action: closures são importantes, muito importantes, são de longe um dos recursos mais importantes do groovy.

Closure é um bloco de codígo encapsulado em um objeto. Definição tambem do Groovy in action.

Para os que estão acostumados com desenvolvimento java e já teve a oportunidade de escrever uma closure ,deve ter notado que seu fluxo lógico é diferente do tradicional, mas assim que nos acostumamos com o seu estilo de escrita os algoritmos fluem como água.
Um simples exemplo de closure utilizado na documentação do groovy é o seguinte:

def clos = { print “Hello”}
// - clos2: Onde a closure recebera algum valor na sua chamada e imprimirá o mesmo.
def clos2 = {print it}.
clos2(‘Hello’) /*Onde o mesmo imprime Hello*/

Também da documentação do groovy, temos dois exemplos bem interessantes de closures para listas.
Suponha que você precise varrer uma determinada lista e aplicar alguma lógica em cada item antes de inseri-los em outra lista.

Pois bem… Temos basicamente duas formas simples de fazer isso no groovy.
1 – Podemos utilizar o collect aplicando a logica para cada item iterado:

def list = ['a','e','i''o','u']
def newList = []

list.collect( newList ) { it.toUpperCase() }

Definição: Foi criada uma lista com as vogais e uma lista vazia que receberá o maiúsculo de cada vogal.
Neste caso o collect é utilizado para aplicar a logica ao it (variável default no groovy para closures com apenas um parâmetro – neste caso uma outra lista) e inseri-lo na lista passada por parâmetro.
Logo no final teremos a seguinte lista [“A”, “E”, “I”, “O”, “U”]

2 – Digamos que a logica a ser aplicada a cada item é um pouco mais complicada, também podemos encapsula-la em outra closure.

def list = ['a','e','i','o','u']
def newList = []

def closAux = { it.toUpperCase() }
list.collect( newList, closAux)

Definição: Neste caso estamos trabalhando com a mesma lógica, mas aqui podemos aproveitar a segunda closure para encapsular uma lógica mais complexa a ser atribuída a cada atributo da lista iterada.
Aqui, temos uma nova closure criada que atribui uma lógica (no it) para no final retorna-lo.
Logo em seguida podemos chamar o collect passando a nova lista e a closure. Pronto, a logica da closure passada por parâmetro será utilizada para cada item iterado da lista e atribuindo a nova lista.

Por fim. É claro que não paramos por aqui. Closures no groovy pode se transformar em um mundo quando utilizamos a boa e velha lógica de programação em conjunto com os conceitos da linguagem.

Lembrando que este post foi só um esclarecimento de closure para dar continuidade nos próximos posts.

Por: Jonatas Emidio

Etiquetado

Criando minha primeira aplicação em Grails

Após configurarmos o ambiente de desenvolvimento , estaremos aptos a criar nossas aplicações.

Antes de criarmos nossa aplicação, precisamos estar pelo menos familiarizados com os comandos principais do Grails, para ter uma noção melhor do que está acontecendo por de traz dos panos quando estivermos utilizando uma IDE.

grails [comando nome]

Rode no DOS o comando create-app para criar a sua aplicação:

grails create-app loja

Após clicar em Enter será criada uma pasta com o nome do projeto, onde dentro estarão os arquivos default de uma aplicação grails.

Acessa o diretório do projeto:

cd loja

Agora que temos a nossa aplicação podemos iniciar a logica do nosso negócio.

Primeiro criaremos a nossa classe de domínio:

grails create-domain-class Produto

Agora que temos a nossa  classe de domínio, devemos inserir na mesma seus atributos:

Acesse o diretorio  do projeto e abra o arquivo gerado para a classe Produto.groovy

Detalhamento do diretório acima:

  1. Loja: Pasta da aplicação, gerada após o  create-app;
  2. Grails-app: pasta responsável por todo o negócio e definições de infraestrutura da aplicação. Ex: dominios, controladores, arquivos de configuração de banco, etc.
  3. Domain: Pasta responsável por armazenar todas as classes de domínio do nosso negócio.
  4. Loja (dentro de domain): Por padrão o grails cria uma package para a classe de dominio com o nome do projeto.

Dentro esta o Produto.groovy, o arquivo e dominio que será alterado para atender o negócio.

Abra o arquivo Produto.groovy e insira os atributos (String nome, double preco, int quantidade).

Segue conteudo da classe após alteração:

package loja
class Produto {
    String nome
    double preco
    int quantidade
    static constraints = {     }
}

Para o domínio é apenas isso, por default os atributos no grails são private e tambem por default temos os gets e sets de cada atributo. [Para frente veremos mais detalhes sobre os encapsulamentos e acesso a atributos].

Salve o arquivo e volta para o prompt de comando.

Agora vocês serão apresentados a um comando considerado como palavra mágica para muitos desenvolvedores grails (generate-all).

grails generate-all loja.Produto

Por incrivel que pareça, este simples comando já gerou todo o CRUD do sistema e as Views com o template default do grails, ou seja… Aqui já temos uma aplicação funcional!!

Vamos executar a nossa aplicação, é isso mesmo, já podemos executar e testar nossa aplicação com o seguinte comando:

grails run-app

Pronto… caso agora podemos acessar a nossa aplicação com a seguinte url: http://localhost:8080/loja

Onde, se clicarmos no link do controlador temos acesso a tela de cadastro, alteração, consulta e exclusão do nosso domínio:

Por fim, com esses simples comandos criamos uma apliação (básica) para lojas de cadastro de produtos.

Lembrando que nossa aplicação esta toda default, em breve veremos como alterar template, linguagem e muito mais. Sempre priorizando a simplicidade e a limpeza de código.

Por: Jonatas Emidio