T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

115
De Java a Groovy: ¡Hora de Aventuras! Iván López @ilopmar

Transcript of T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

Page 1: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

De Java a Groovy:¡Hora de Aventuras!Iván López @ilopmar

Page 2: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

➢ Iván López @ilopmar

➢ Groovy & Grails developer

➢ Coordinador de @madridgug

➢ Organizador de Greach@greachconfhttp://greachconf.com

➢ Speaker: SpringOne 2GX, GR8Conf,GGX, Codemotion, GeeCon, jDays,Spring IO, Greach, ConFess,...

Sobre mí...

Page 3: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

1.Qué es Groovy

Page 4: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

“Groovy es un lenguaje dinámico poderoso, opcionalmente tipado, con capacidad de tipado y compilación estáticos para la plataforma Java centrado en multiplicar la productividad de los desarrolladores gracias a una sintaxis concisa, familiar y fácil de aprender.

Se integra sin problemas con cualquier programa Java e inmediatamente proporciona a tu aplicación poderosas características como capacidades de scripting, DSLs, metaprogramación en runtime y compile-time y programación funcional.

– Web de Groovy

Page 5: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

“Groovy es un lenguaje dinámico poderoso, opcionalmente tipado, con capacidad de tipado y compilación estáticos para la plataforma Java centrado en multiplicar la productividad de los desarrolladores gracias a una sintaxis concisa, familiar y fácil de aprender.

Se integra sin problemas con cualquier programa Java e inmediatamente proporciona a tu aplicación poderosas características como capacidades de scripting, DSLs, metaprogramación en runtime y compile-time y programación funcional.

– Web de Groovy

Page 6: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

“Groovy es un lenguaje dinámico poderoso, opcionalmente tipado, con capacidad de tipado y compilación estáticos para la plataforma Java centrado en multiplicar la productividad de los desarrolladores gracias a una sintaxis concisa, familiar y fácil de aprender.

Se integra sin problemas con cualquier programa Java e inmediatamente proporciona a tu aplicación poderosas características como capacidades de scripting, DSLs, metaprogramación en runtime y compile-time y programación funcional.

– Web de Groovy

Page 7: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

“Groovy es un lenguaje dinámico poderoso, opcionalmente tipado, con capacidad de tipado y compilación estáticos para la plataforma Java centrado en multiplicar la productividad de los desarrolladores gracias a una sintaxis concisa, familiar y fácil de aprender.

Se integra sin problemas con cualquier programa Java e inmediatamente proporciona a tu aplicación poderosas características como capacidades de scripting, DSLs, metaprogramación en runtime y compile-time y programación funcional.

– Web de Groovy

Page 8: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

“Groovy es un lenguaje dinámico poderoso, opcionalmente tipado, con capacidad de tipado y compilación estáticos para la plataforma Java centrado en multiplicar la productividad de los desarrolladores gracias a una sintaxis concisa, familiar y fácil de aprender.

Se integra sin problemas con cualquier programa Java e inmediatamente proporciona a tu aplicación poderosas características como capacidades de scripting, DSLs, metaprogramación en runtime y compile-time y programación funcional.

– Web de Groovy

Page 9: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

“Groovy es un lenguaje dinámico poderoso, opcionalmente tipado, con capacidad de tipado y compilación estáticos para la plataforma Java centrado en multiplicar la productividad de los desarrolladores gracias a una sintaxis concisa, familiar y fácil de aprender.

Se integra sin problemas con cualquier programa Java e inmediatamente proporciona a tu aplicación poderosas características como capacidades de scripting, DSLs, metaprogramación en runtime y compile-time y programación funcional.

– Web de Groovy

Page 10: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

“Groovy es un lenguaje dinámico poderoso, opcionalmente tipado, con capacidad de tipado y compilación estáticos para la plataforma Java centrado en multiplicar la productividad de los desarrolladores gracias a una sintaxis concisa, familiar y fácil de aprender.

Se integra sin problemas con cualquier programa Java e inmediatamente proporciona a tu aplicación poderosas características como capacidades de scripting, DSLs, metaprogramación en runtime y compile-time y programación funcional.

– Web de Groovy

Page 11: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

“Groovy es un lenguaje dinámico poderoso, opcionalmente tipado, con capacidad de tipado y compilación estáticos para la plataforma Java centrado en multiplicar la productividad de los desarrolladores gracias a una sintaxis concisa, familiar y fácil de aprender.

Se integra sin problemas con cualquier programa Java e inmediatamente proporciona a tu aplicación poderosas características como capacidades de scripting, DSLs, metaprogramación en runtime y compile-time y programación funcional.

– Web de Groovy

Page 12: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

“Groovy es un lenguaje dinámico poderoso, opcionalmente tipado, con capacidad de tipado y compilación estáticos para la plataforma Java centrado en multiplicar la productividad de los desarrolladores gracias a una sintaxis concisa, familiar y fácil de aprender.

Se integra sin problemas con cualquier programa Java e inmediatamente proporciona a tu aplicación poderosas características como capacidades de scripting, DSLs, metaprogramación en runtime y compile-time y programación funcional.

– Web de Groovy

Page 13: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

“Groovy es un lenguaje dinámico poderoso, opcionalmente tipado, con capacidad de tipado y compilación estáticos para la plataforma Java centrado en multiplicar la productividad de los desarrolladores gracias a una sintaxis concisa, familiar y fácil de aprender.

Se integra sin problemas con cualquier programa Java e inmediatamente proporciona a tu aplicación poderosas características como capacidades de scripting, DSLs, metaprogramación en runtime y compile-time y programación funcional.

– Web de Groovy

Page 14: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

“Groovy es un lenguaje dinámico poderoso, opcionalmente tipado, con capacidad de tipado y compilación estáticos para la plataforma Java centrado en multiplicar la productividad de los desarrolladores gracias a una sintaxis concisa, familiar y fácil de aprender.

Se integra sin problemas con cualquier programa Java e inmediatamente proporciona a tu aplicación poderosas características como capacidades de scripting, DSLs, metaprogramación en runtime y compile-time y programación funcional.

– Web de Groovy

Page 15: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

Groovy

Page 16: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

2.¿Y por qué no Java?

Page 17: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

➢ Java es sólido

➢ Conocido por muchos desarrolladores

➢ Muy extendido

➢ Es rápido

Pero...

➢ Java es verboso

➢ Puede ser incómodo en algunos casos

➢ No es dinámico

¿Y por qué no Java?

Page 18: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

3.Haciendo Java Groovy

Page 19: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

public class Saludador { private String saludo;

public void diHolaA(String... nombres) { String mensajeSaludo = prepararMensajeSaludo(nombres); System.out.println(mensajeSaludo); }

public String getSaludo() { return saludo; }

public void setSaludo(String saludo) { this.saludo = saludo; }

private String prepararMensajeSaludo(String... nombres) { String delimitador = ""; StringBuilder sb = new StringBuilder(); for (String nombre : nombres) { sb.append(delimitador).append(nombre); delimitador = ", "; } return this.saludo + " " + sb.toString() + "!"; }

public static void main(String[] args) { final Saludador saludador = new Saludador(); saludador.setSaludo("Hola"); saludador.diHolaA("Sheldon", "Leonard", "Raj", "Howard"); }}

Saludador.javaRenombrar

Page 20: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

public class Saludador { private String saludo;

public void diHolaA(String... nombres) { String mensajeSaludo = prepararMensajeSaludo(nombres); System.out.println(mensajeSaludo); }

public String getSaludo() { return saludo; }

public void setSaludo(String saludo) { this.saludo = saludo; }

private String prepararMensajeSaludo(String... nombres) { String delimitador = ""; StringBuilder sb = new StringBuilder(); for (String nombre : nombres) { sb.append(delimitador).append(nombre); delimitador = ", "; } return this.saludo + " " + sb.toString() + "!"; }

public static void main(String[] args) { final Saludador saludador = new Saludador(); saludador.setSaludo("Hola"); saludador.diHolaA("Sheldon", "Leonard", "Raj", "Howard"); }}

Saludador.groovy

Page 21: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

public class Saludador { private String saludo;

public void diHolaA(String... nombres) { String mensajeSaludo = prepararMensajeSaludo(nombres); System.out.println(mensajeSaludo); }

public String getSaludo() { return saludo; }

public void setSaludo(String saludo) { this.saludo = saludo; }

private String prepararMensajeSaludo(String... nombres) { String delimitador = ""; StringBuilder sb = new StringBuilder(); for (String nombre : nombres) { sb.append(delimitador).append(nombre); delimitador = ", "; } return this.saludo + " " + sb.toString() + "!"; }

public static void main(String[] args) { final Saludador saludador = new Saludador(); saludador.setSaludo("Hola"); saludador.diHolaA("Sheldon", "Leonard", "Raj", "Howard"); }}

Groovy

Page 22: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

public class Saludador { private String saludo

public void diHolaA(String... nombres) { String mensajeSaludo = prepararMensajeSaludo(nombres) System.out.println(mensajeSaludo) }

public String getSaludo() { return saludo }

public void setSaludo(String saludo) { this.saludo = saludo }

private String prepararMensajeSaludo(String... nombres) { String delimitador = "" StringBuilder sb = new StringBuilder() for (String nombre : nombres) { sb.append(delimitador).append(nombre) delimitador = ", " } return this.saludo + " " + sb.toString() + "!" }

public static void main(String[] args) { final Saludador saludador = new Saludador() saludador.setSaludo("Hola") saludador.diHolaA("Sheldon", "Leonard", "Raj", "Howard") }}

opcional

opcional

Groovy

Page 23: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

class Saludador { private String saludo

void diHolaA(String... nombres) { String mensajeSaludo = prepararMensajeSaludo(nombres) System.out.println(mensajeSaludo) }

String getSaludo() { return saludo }

void setSaludo(String saludo) { this.saludo = saludo }

private String prepararMensajeSaludo(String... nombres) { String delimitador = "" StringBuilder sb = new StringBuilder() for (String nombre : nombres) { sb.append(delimitador).append(nombre) delimitador = ", " } return this.saludo + " " + sb.toString() + "!" }

static void main(String[] args) { final Saludador saludador = new Saludador() saludador.setSaludo("Hola") saludador.diHolaA("Sheldon", "Leonard", "Raj", "Howard") }}

getter y setterverbosos

Groovy

Page 24: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

class Saludador { String saludo

void diHolaA(String... nombres) { String mensajeSaludo = prepararMensajeSaludo(nombres) System.out.println(mensajeSaludo) }

private String prepararMensajeSaludo(String... nombres) { String delimitador = "" StringBuilder sb = new StringBuilder() for (String nombre : nombres) { sb.append(delimitador).append(nombre) delimitador = ", " } return this.saludo + " " + sb.toString() + "!" }

static void main(String[] args) { final Saludador saludador = new Saludador() saludador.setSaludo("Hola") saludador.diHolaA("Sheldon", "Leonard", "Raj", "Howard") }}

Acceso comopropiedad

Groovy

Page 25: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

class Saludador { String saludo

void diHolaA(String... nombres) { String mensajeSaludo = prepararMensajeSaludo(nombres) System.out.println(mensajeSaludo) }

private String prepararMensajeSaludo(String... nombres) { String delimitador = "" StringBuilder sb = new StringBuilder() for (String nombre : nombres) { sb.append(delimitador).append(nombre) delimitador = ", " } return this.saludo + " " + sb.toString() + "!" }

static void main(String[] args) { final Saludador saludador = new Saludador() saludador.saludo = "Hola" saludador.diHolaA("Sheldon", "Leonard", "Raj", "Howard") }}

opcional

Groovy

Page 26: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

class Saludador { String saludo

void diHolaA(String... nombres) { String mensajeSaludo = prepararMensajeSaludo(nombres) System.out.println(mensajeSaludo) }

private String prepararMensajeSaludo(String... nombres) { String delimitador = "" StringBuilder sb = new StringBuilder() for (String nombre : nombres) { sb.append(delimitador).append(nombre) delimitador = ", " } this.saludo + " " + sb.toString() + "!" }

static void main(String[] args) { final Saludador saludador = new Saludador() saludador.saludo = "Hola" saludador.diHolaA("Sheldon", "Leonard", "Raj", "Howard") }}

atajo

Groovy

Page 27: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

class Saludador { String saludo

void diHolaA(String... nombres) { String mensajeSaludo = prepararMensajeSaludo(nombres) println(mensajeSaludo) }

private String prepararMensajeSaludo(String... nombres) { String delimitador = "" StringBuilder sb = new StringBuilder() for (String nombre : nombres) { sb.append(delimitador).append(nombre) delimitador = ", " } this.saludo + " " + sb.toString() + "!" }

static void main(String[] args) { final Saludador saludador = new Saludador() saludador.saludo = "Hola" saludador.diHolaA("Sheldon", "Leonard", "Raj", "Howard") }}

API decolecciones

Groovy

Page 28: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

class Saludador { String saludo

void diHolaA(String... nombres) { String mensajeSaludo = prepararMensajeSaludo(nombres) println(mensajeSaludo) }

private String prepararMensajeSaludo(String... nombres) { String nombreUnidos = nombres.join(', ') this.saludo + " " + nombresUnidos + "!" }

static void main(String[] args) { final Saludador saludador = new Saludador() saludador.saludo = "Hola" saludador.diHolaA("Sheldon", "Leonard", "Raj", "Howard") }}

interpolaciónde String (GString)

Groovy

Page 29: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

class Saludador { String saludo

void diHolaA(String... nombres) { String mensajeSaludo = prepararMensajeSaludo(nombres) println(mensajeSaludo) }

private String prepararMensajeSaludo(String... nombres) { String nombreUnidos = nombres.join(', ')

"${this.saludo} $nombreUnidos!" }

static void main(String[] args) { final Saludador saludador = new Saludador() saludador.saludo = "Hola" saludador.diHolaA("Sheldon", "Leonard", "Raj", "Howard") }}

refactor

Groovy

Page 30: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

class Saludador { String saludo

void diHolaA(String... nombres) { String mensajeSaludo = prepararMensajeSaludo(nombres) println(mensajeSaludo) }

private String prepararMensajeSaludo(String... nombres) { "$saludo ${nombres.join(', ')}!"

}

static void main(String[] args) { final Saludador saludador = new Saludador() saludador.saludo = "Hola" saludador.diHolaA("Sheldon", "Leonard", "Raj", "Howard") }}

tipadoopcional

Groovy

Page 31: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

class Saludador { String saludo

void diHolaA(String... nombres) { def mensajeSaludo = prepararMensajeSaludo(nombres) println(mensajeSaludo) }

private String prepararMensajeSaludo(String... nombres) { "$saludo ${nombres.join(', ')}!"

}

static void main(String[] args) { def saludador = new Saludador() saludador.saludo = "Hola" saludador.diHolaA("Sheldon", "Leonard", "Raj", "Howard") }}

namedconstructor

Groovy

Page 32: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

class Saludador { String saludo

void diHolaA(String... nombres) { def mensajeSaludo = prepararMensajeSaludo(nombres) println(mensajeSaludo) }

private String prepararMensajeSaludo(String... nombres) { "$saludo ${nombres.join(', ')}!"

}

static void main(String[] args) { def saludador = new Saludador(saludo: 'Hola') saludador.diHolaA("Sheldon", "Leonard", "Raj", "Howard") }}

paréntesisopcionales

paréntesisopcionales

Groovy

Page 33: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

class Saludador { String saludo

void diHolaA(String... nombres) { def mensajeSaludo = prepararMensajeSaludo(nombres) println mensajeSaludo }

private String prepararMensajeSaludo(String... nombres) { "$saludo ${nombres.join(', ')}!"

}

static void main(String[] args) { def saludador = new Saludador(saludo: 'Hola') saludador.diHolaA "Sheldon", "Leonard", "Raj", "Howard" }}

main comoscript

Groovy

Page 34: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

class Saludador { String saludo

void diHolaA(String... nombres) { def mensajeSaludo = prepararMensajeSaludo(nombres) println mensajeSaludo }

private String prepararMensajeSaludo(String... nombres) { "$saludo ${nombres.join(', ')}!"

}} saludador = new Saludador(saludo: 'Hola') saludador.diHolaA "Sheldon", "Leonard", "Raj", "Howard"

refactor

Groovy

Page 35: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

class Saludador { String saludo

void diHolaA(String... nombres) { println "$saludo ${nombres.join(', ')}!" }

} saludador = new Saludador(saludo: 'Hola') saludador.diHolaA "Sheldon", "Leonard", "Raj", "Howard"

Limpiemoslos espacios

Groovy

Page 36: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

class Saludador { String saludo

void diHolaA(String... nombres) { println "$saludo ${nombres.join(', ')}!" }}

saludador = new Saludador(saludo: 'Hola')saludador.diHolaA "Sheldon", "Leonard", "Raj", "Howard"

Groovy: Versión final

Page 37: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

class Saludador { String saludo

void diHolaA(String... nombres) { println "$saludo ${nombres.join(', ')}!" }}

saludador = new Saludador(saludo: 'Hola')saludador.diHolaA "Sheldon", "Leonard", "Raj", "Howard"

Groovy: Versión final

Java 32 líneas 900 caracteres

Groovy 10 líneas 231 caracteres

Diferencia 68% 74%

Page 38: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

Groovy: ¡Hora de Aventuras!

Page 39: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

4.Groovy

Page 40: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

➢ Dinámico

➢ Compilación estática opcional

➢ Todo es un objeto

➢ Sobrecarga de operadores➢ + es .plus()➢ * es .multiply()

➢ Sintaxis nativa de listas, mapas y rangos

➢ Métodos y clases public por defecto

➢ Las excepciones son unchecked

➢ http://groovy-lang.org/differences.html

Diferencias entre Java y Groovy

Page 41: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

Getters y setters

public class Persona {

private String nombre; private int edad;

String getNombre() { return nombre; }

void setNombre(String nombre) { this.nombre = nombre; }

int getEdad() { return edad; }

void setEdad(int edad) { this.edad = edad; }}

Page 42: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

Getters y setters

public class Persona {

private String nombre; private int edad;

String getNombre() { return nombre; }

void setNombre(String nombre) { this.nombre = nombre; }

int getEdad() { return edad; }

void setEdad(int edad) { this.edad = edad; }}

class Persona { String nombre int edad}

Page 43: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

Named constructors

class Persona { String nombre int edad}

def p = new Persona(nombre: 'Iván', edad: 36)assert p.nombre == 'Iván'

p.edad = 37assert p.edad == 37

Page 44: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

Constructor Builder

import groovy.transform.builder.Builder

@Builderclass Persona { String nombre int edad}

Persona.builder() .nombre('Iván') .edad(36) .build()

Page 45: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

Números que...

System.out.println(2.00 - 1.1);// 0.8999999999999999

Page 46: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

Números que...

System.out.println(2.00 - 1.1);// 0.8999999999999999

Page 47: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

Números que...

System.out.println(3 / 2);// 1

Page 48: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

Números que...

System.out.println(3 / 2);// 1

Page 49: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

¡BigDecimal por defecto!

assert 2.0 - 1.1 == 0.9assert 3 / 2 == 1.5

Page 50: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

Equals y ==

estado != null && estado.equals(Estado.COMPLETADO);

Page 51: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

Equals y ==

estado == Estado.COMPLETADO

estado != null && estado.equals(Estado.COMPLETADO);

Page 52: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

Strings y GString

def nombre = 'Iván'def edad = 36

println "¡Hola ${nombre}, tienes ${edad} años!"

def query = """insert into people (firstName, age)values (${nombre}, ${edad})"""

new Sql(datasource).execute query

Page 53: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

Strings y GString

def nombre = 'Iván'def edad = 36

println "¡Hola ${nombre}, tienes ${edad} años!"

def query = """insert into people (firstName, age)values (${nombre}, ${edad})"""

new Sql(datasource).execute query

Page 54: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

Listas

def list = ['a', 'b', 'c']

list << 'd' // list.add(“d”)assert list.contains('d')

assert list.collect { it.toUpperCase() } == ['A', 'B', 'C', 'D']assert list.findAll { it.startsWith 'a' }.size() == 1

Page 55: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

Listas

def list = ['a', 'b', 'c']

list << 'd' // list.add(“d”)assert list.contains('d')

assert list.collect { it.toUpperCase() } == ['A', 'B', 'C', 'D']assert list.findAll { it.startsWith 'a' }.size() == 1

Page 56: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

Listas

def list = ['a', 'b', 'c']

list << 'd' // list.add(“d”)assert list.contains('d')

assert list.collect { it.toUpperCase() } == ['A', 'B', 'C', 'D']assert list.findAll { it.startsWith 'a' }.size() == 1

Page 57: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

Mapas

def map = [nombre: 'Iván', edad: 36]assert map.nombre == 'Iván'

map.hijas = ['Judith', 'Adriana']assert map['hijas'].contains('Adriana')

Page 58: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

Mapas

def map = [nombre: 'Iván', edad: 36]assert map.nombre == 'Iván'

map.hijas = ['Judith', 'Adriana']assert map['hijas'].contains('Adriana')

def map = [nombre: 'Iván', edad: 36]assert map.nombre == 'Iván'

map.hijas = ['Judith', 'Adriana']assert map['hijas'].contains('Adriana')

Page 59: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

Rangos

def rango = 'a'..'z'assert rango.contains('i')assert rango.contains('z')

def exclusivo = 1..<10assert !exclusivo.contains(10)

def inverso = 10..1assert inverso[0] == 10assert inverso[-1] == 1

Page 60: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

Rangos

def rango = 'a'..'z'assert rango.contains('i')assert rango.contains('z')

def exclusivo = 1..<10assert !exclusivo.contains(10)

def inverso = 10..1assert inverso[0] == 10assert inverso[-1] == 1

Page 61: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

Rangos

def rango = 'a'..'z'assert rango.contains('i')assert rango.contains('z')

def exclusivo = 1..<10assert !exclusivo.contains(10)

def inverso = 10..1assert inverso[0] == 10assert inverso[-1] == 1

Page 62: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

Groovy truth

assert !( null )assert !( "" )assert !( '' )assert !( [] )assert !( [:] )assert !( 0 )

Page 63: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

Groovy truth

false

assert !( null )assert !( "" )assert !( '' )assert !( [] )assert !( [:] )assert !( 0 )

Page 64: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

Groovy truth

assert new Object()assert "string"assert 'string'assert [1, 2]assert [a: 1]assert 1

false

assert !( null )assert !( "" )assert !( '' )assert !( [] )assert !( [:] )assert !( 0 )

Page 65: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

Groovy truth

assert new Object()assert "string"assert 'string'assert [1, 2]assert [a: 1]assert 1

false

true

assert !( null )assert !( "" )assert !( '' )assert !( [] )assert !( [:] )assert !( 0 )

Page 66: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

Power asserts

assert (2 + 7) * 5 != (2 * 5) + (7 * 5)

(2 + 7) * 5 != (2 * 5) + (7 * 5) | | | | | | 9 45 false 10 45 35

Page 67: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

Power asserts

assert (2 + 7) * 5 != (2 * 5) + (7 * 5)

(2 + 7) * 5 != (2 * 5) + (7 * 5) | | | | | | 9 45 false 10 45 35

Page 68: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

Power asserts

def info = [ nombre: 'Iván', edad: 36, hijas: [ [nombre: 'Judith', edad: 8], [nombre: 'Adriana', edad: 5] ]]

assert info.hijas.nombre.first() == 'Adriana'

info.hijas.nombre.first() == 'Adriana'| | | | || | | Judith false| | | 6 differences (14% similarity)| | | (Ju)d(-)i(th-)| | | (A-)d(r)i(ana)| | [Judith, Adriana]| [[nombre:Judith, edad:8], [nombre:Adriana, edad:5]][nombre:Iván, edad:36, hijas:[[nombre:Judith, edad:8], [nombre:Adriana, edad:5]]]

Page 69: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

Power asserts

def info = [ nombre: 'Iván', edad: 36, hijas: [ [nombre: 'Judith', edad: 8], [nombre: 'Adriana', edad: 5] ]]

assert info.hijas.nombre.first() == 'Adriana'

info.hijas.nombre.first() == 'Adriana'| | | | || | | Judith false| | | 6 differences (14% similarity)| | | (Ju)d(-)i(th-)| | | (A-)d(r)i(ana)| | [Judith, Adriana]| [[nombre:Judith, edad:8], [nombre:Adriana, edad:5]][nombre:Iván, edad:36, hijas:[[nombre:Judith, edad:8], [nombre:Adriana, edad:5]]]

Page 70: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

Power asserts

def info = [ nombre: 'Iván', edad: 36, hijas: [ [nombre: 'Judith', edad: 8], [nombre: 'Adriana', edad: 5] ]]

assert info.hijas.nombre.first() == 'Adriana'

info.hijas.nombre.first() == 'Adriana'| | | | || | | Judith false| | | 6 differences (14% similarity)| | | (Ju)d(-)i(th-)| | | (A-)d(r)i(ana)| | [Judith, Adriana]| [[nombre:Judith, edad:8], [nombre:Adriana, edad:5]][nombre:Iván, edad:36, hijas:[[nombre:Judith, edad:8], [nombre:Adriana, edad:5]]]

Page 71: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

Power asserts

def info = [ nombre: 'Iván', edad: 36, hijas: [ [nombre: 'Judith', edad: 8], [nombre: 'Adriana', edad: 5] ]]

assert info.hijas.nombre.first() == 'Adriana'

info.hijas.nombre.first() == 'Adriana'| | | | || | | Judith false| | | 6 differences (14% similarity)| | | (Ju)d(-)i(th-)| | | (A-)d(r)i(ana)| | [Judith, Adriana]| [[nombre:Judith, edad:8], [nombre:Adriana, edad:5]][nombre:Iván, edad:36, hijas:[[nombre:Judith, edad:8], [nombre:Adriana, edad:5]]]

Page 72: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

Power asserts

def info = [ nombre: 'Iván', edad: 36, hijas: [ [nombre: 'Judith', edad: 8], [nombre: 'Adriana', edad: 5] ]]

assert info.hijas.nombre.first() == 'Adriana'

info.hijas.nombre.first() == 'Adriana'| | | | || | | Judith false| | | 6 differences (14% similarity)| | | (Ju)d(-)i(th-)| | | (A-)d(r)i(ana)| | [Judith, Adriana]| [[nombre:Judith, edad:8], [nombre:Adriana, edad:5]][nombre:Iván, edad:36, hijas:[[nombre:Judith, edad:8], [nombre:Adriana, edad:5]]]

Page 73: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

def info = [ nombre: 'Iván', edad: 36, hijas: [ [nombre: 'Judith', edad: 8], [nombre: 'Adriana', edad: 5] ]]

assert info.hijas.nombre.first() == 'Adriana'

info.hijas.nombre.first() == 'Adriana'| | | | || | | Judith false| | | 6 differences (14% similarity)| | | (Ju)d(-)i(th-)| | | (A-)d(r)i(ana)| | [Judith, Adriana]| [[nombre:Judith, edad:8], [nombre:Adriana, edad:5]][nombre:Iván, edad:36, hijas:[[nombre:Judith, edad:8], [nombre:Adriana, edad:5]]]

Power asserts

Page 74: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

Elvis

List resultado = (nombres != null && nombres.size() > 0) ? nombres : Collections.emptyList();

Page 75: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

Elvis

List resultado = (nombres != null && nombres.size() > 0) ? nombres : Collections.emptyList();

def resultado = nombres ? nombres : []

Page 76: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

Elvis

List resultado = (nombres != null && nombres.size() > 0) ? nombres : Collections.emptyList();

def resultado = nombres ? nombres : []

def resultado = nombres ?: []

Page 77: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

Safe navigation

if (order != null) { if (order.getCustomer() != null) { if (order.getCustomer().getAddress() != null) { System.out.println(order.getCustomer().getAddress()); } }}

Page 78: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

Safe navigation

if (order != null) { if (order.getCustomer() != null) { if (order.getCustomer().getAddress() != null) { System.out.println(order.getCustomer().getAddress()); } }}

println order?.customer?.address

Page 79: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

Closures

def multiplicador = { a, b -> a * b }

assert multiplicador(2, 3) == 6assert multiplicador.call(2, 3) == 6assert multiplicador('=', 8) == '========'

def sumador = { ... numbers -> numbers.sum() }assert sumador(1, 2, 3) == 6assert sumador('a', 'b', 'c') == 'abc'

def multiplicador = { int a, int b -> a * b }

Page 80: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

def multiplicador = { a, b -> a * b }

assert multiplicador(2, 3) == 6assert multiplicador.call(2, 3) == 6assert multiplicador('=', 8) == '========'

def sumador = { ... numbers -> numbers.sum() }assert sumador(1, 2, 3) == 6assert sumador('a', 'b', 'c') == 'abc'

def multiplicador = { int a, int b -> a * b }

Closures

Page 81: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

def multiplicador = { a, b -> a * b }

assert multiplicador(2, 3) == 6assert multiplicador.call(2, 3) == 6assert multiplicador('=', 8) == '========'

def sumador = { ... numbers -> numbers.sum() }assert sumador(1, 2, 3) == 6assert sumador('a', 'b', 'c') == 'abc'

def multiplicador = { int a, int b -> a * b }

Closures

Page 82: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

Closures: Valores por defecto

def multiplicador = { int a, int b = 10 -> a * b }

assert multiplicador(2, 3) == 6assert multiplicador(2) == 20

Page 83: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

Closures: Métodos como función

def logBase10 = Math.&log10assert logBase10(10) == 1

Page 84: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

Closures: map, filter, reduce

def personas = [ new Persona('Iván', 36), new Persona('Judith', 8), new Persona('Adriana', 5)]

def nombres = personas.findAll { it.edad < 18 } .collect { it.nombre.toUpperCase() } .sort() .join(', ')

assert nombres == 'ADRIANA, JUDITH'

Page 85: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

Closures: map, filter, reduce

def personas = [ new Persona('Iván', 36), new Persona('Judith', 8), new Persona('Adriana', 5)]

def nombres = personas.findAll { it.edad < 18 } .collect { it.nombre.toUpperCase() } .sort() .join(', ')

assert nombres == 'ADRIANA, JUDITH'

Page 86: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

Closures: map, filter, reduce

def personas = [ new Persona('Iván', 36), new Persona('Judith', 8), new Persona('Adriana', 5)]

def nombres = personas.findAll { it.edad < 18 } .collect { it.nombre.toUpperCase() } .sort() .join(', ')

assert nombres == 'ADRIANA, JUDITH'

Page 87: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

Groovy Closures y Java 8 Lambdasimport static java.util.Arrays.asList;

public class JavaLambdas { public static void main(String[] args) { asList(1, 2, 3).stream() .map(i -> i * 2) .filter(i -> i > 3) .findFirst() .orElseThrow(IllegalArgumentException::new); }}

Page 88: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

Groovy Closures y Java 8 Lambdasimport static java.util.Arrays.asList;

public class JavaLambdas { public static void main(String[] args) { asList(1, 2, 3).stream() .map(i -> i * 2) .filter(i -> i > 3) .findFirst() .orElseThrow(IllegalArgumentException::new); }}

[1, 2, 3].stream() .map { i -> i * 2 } .filter { i -> i > 3 } .findFirst() .orElseThrow(IllegalArgumentException.&newInstance)

Page 89: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

Json builder

{ "speaker": { "firstName": "Iván", "lastName": "López", "address": { "city": "Madrid", "country": "España", "zip": 12345 }, "conferences": [ "T3chFest", "Codemotion", "Greach" ] }}

import groovy.json.JsonBuilder

def builder = new JsonBuilder()builder. speaker { firstName 'Iván' lastName 'López' address( city: 'Madrid', country: 'España', zip: 12345, ) conferences( 'T3chFest', 'Codemotion', 'Greach' ) }

println builder.toPrettyString()

Page 90: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

Json builder

{ "speaker": { "firstName": "Iván", "lastName": "López", "address": { "city": "Madrid", "country": "España", "zip": 12345 }, "conferences": [ "T3chFest", "Codemotion", "Greach" ] }}

import groovy.json.JsonBuilder

def builder = new JsonBuilder()builder. speaker { firstName 'Iván' lastName 'López' address( city: 'Madrid', country: 'España', zip: 12345, ) conferences( 'T3chFest', 'Codemotion', 'Greach' ) }

println builder.toPrettyString()

Page 91: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

Parsear XML y Json en Java

Page 92: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

Json parser

wind: { speed: 2.1, deg: 350 }, clouds: { all: 75 }, dt: 1454061483, sys: { type: 1, id: 5488, message: 0.0046, country: "ES", sunrise: 1454052430, sunset: 1454088574 }, id: 3118594, name: "Leganes", cod: 200}

http://api.openweathermap.org/data/2.5/weather?units=metric&q=Leganes&appid=...

{ coord: { lon: -3.76, lat: 40.33 }, weather: [ { id: 300, main: "Drizzle", description: "few clouds", icon: "09d" } ], base: "cmc stations", main: { temp: 8.21, pressure: 1032, humidity: 87, temp_min: 8, temp_max: 8.6 },

Page 93: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

Json parserhttp://api.openweathermap.org/data/2.5/weather?units=metric&q=Leganes&appid=...

wind: { speed: 2.1, deg: 350 }, clouds: { all: 75 }, dt: 1454061483, sys: { type: 1, id: 5488, message: 0.0046, country: "ES", sunrise: 1454052430, sunset: 1454088574 }, id: 3118594, name: "Leganes", cod: 200}

{ coord: { lon: -3.76, lat: 40.33 }, weather: [ { id: 300, main: "Drizzle", description: "few clouds", icon: "09d" } ], base: "cmc stations", main: { temp: 8.21, pressure: 1032, humidity: 87, temp_min: 8, temp_max: 8.6 },

Page 94: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

Json parser

import groovy.json.JsonSlurper

def url = "http://api.openweathermap.org/data/2.5/weather?units=metric&q=Leganes&appid=...".toURL()

def response = new JsonSlurper().parse(url)

String weather = response.weather.collect { it.description }.join(', ')String country = response.sys.countryString temp = response.main.tempString city = response.name

println "Tiempo en ${city} (${country}): ${weather}. Temp: ${temp} ºC"

// Tiempo en Leganes (ES): few clouds. Temp: 8.84 ºC

{ weather: [ { description: "few clouds", } ], main: { temp: 8.21 }, sys: { country: "ES", }, name: "Leganes",}

Page 95: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

Json parser

import groovy.json.JsonSlurper

def url = "http://api.openweathermap.org/data/2.5/weather?units=metric&q=Leganes&appid=...".toURL()

def response = new JsonSlurper().parse(url)

String weather = response.weather.collect { it.description }.join(', ')String country = response.sys.countryString temp = response.main.tempString city = response.name

println "Tiempo en ${city} (${country}): ${weather}. Temp: ${temp} ºC"

// Tiempo en Leganes (ES): few clouds. Temp: 8.84 ºC

{ weather: [ { description: "few clouds", } ], main: { temp: 8.21 }, sys: { country: "ES", }, name: "Leganes",}

Page 96: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

Json parser

import groovy.json.JsonSlurper

def url = "http://api.openweathermap.org/data/2.5/weather?units=metric&q=Leganes&appid=...".toURL()

def response = new JsonSlurper().parse(url)

String weather = response.weather.collect { it.description }.join(', ')String country = response.sys.countryString temp = response.main.tempString city = response.name

println "Tiempo en ${city} (${country}): ${weather}. Temp: ${temp} ºC"

// Tiempo en Leganes (ES): few clouds. Temp: 8.84 ºC

{ weather: [ { description: "few clouds", } ], main: { temp: 8.21 }, sys: { country: "ES", }, name: "Leganes",}

Page 97: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

Json parser

import groovy.json.JsonSlurper

def url = "http://api.openweathermap.org/data/2.5/weather?units=metric&q=Leganes&appid=...".toURL()

def response = new JsonSlurper().parse(url)

String weather = response.weather.collect { it.description }.join(', ')String country = response.sys.countryString temp = response.main.tempString city = response.name

println "Tiempo en ${city} (${country}): ${weather}. Temp: ${temp} ºC"

// Tiempo en Leganes (ES): few clouds. Temp: 8.21 ºC

{ weather: [ { description: "few clouds", } ], main: { temp: 8.21 }, sys: { country: "ES", }, name: "Leganes",}

Page 98: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

Lectura de fichero de texto

static String readFile(File file) throws IOException { byte[] bytes = Files.readAllBytes(file.toPath()); return new String(bytes, "UTF-8");}

public static void main(String[] args) { File file = new File("foo.txt"); try { String content = readFile(file); System.out.println(content); } catch (IOException e) { e.printStackTrace(); }}

Page 99: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

Lectura de fichero de texto

static String readFile(File file) throws IOException { byte[] bytes = Files.readAllBytes(file.toPath()); return new String(bytes, "UTF-8");}

public static void main(String[] args) { File file = new File("foo.txt"); try { String content = readFile(file); System.out.println(content); } catch (IOException e) { e.printStackTrace(); }}

String content = new File('foo.txt').text

Page 100: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

Lectura de fichero de texto

static String readFile(File file) throws IOException { byte[] bytes = Files.readAllBytes(file.toPath()); return new String(bytes, "UTF-8");}

public static void main(String[] args) { File file = new File("foo.txt"); try { String content = readFile(file); System.out.println(content); } catch (IOException e) { e.printStackTrace(); }}

String content = new File('foo.txt').text

Page 101: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

Lectura de una URLimport java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.net.MalformedURLException;import java.net.URL;import java.net.URLConnection;

public class GetURLContent { public static void main(String[] args) {

try { URL url = new URL("http://www.google.com"); URLConnection conn = url.openConnection(); BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream())); String inputLine;

while ((inputLine = br.readLine()) != null) { System.out.println(inputLine); }

br.close(); } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } }}

Page 102: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

Lectura de una URLimport java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.net.MalformedURLException;import java.net.URL;import java.net.URLConnection;

public class GetURLContent { public static void main(String[] args) {

try { URL url = new URL("http://www.google.com"); URLConnection conn = url.openConnection(); BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream())); String inputLine;

while ((inputLine = br.readLine()) != null) { System.out.println(inputLine); }

br.close(); } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } }}

println 'http://www.google.com'.toURL().text

Page 103: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

Lectura de una URLimport java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.net.MalformedURLException;import java.net.URL;import java.net.URLConnection;

public class GetURLContent { public static void main(String[] args) {

try { URL url = new URL("http://www.google.com"); URLConnection conn = url.openConnection(); BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream())); String inputLine;

while ((inputLine = br.readLine()) != null) { System.out.println(inputLine); }

br.close(); } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } }}

println 'http://www.google.com'.toURL().text

Page 104: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

➢ Groovy JDK

➢ Amplía tipos

➢ Añade métodos

➢ http://www.groovy-lang.org/gdk.html

GDK

Page 105: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

5.¡Quiero más!

Page 106: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

DSLs: Domain Specific Languages

def mailer = new Mailer()mailer.setTo('[email protected]', '[email protected]')mailer.setSubject('Urgente!')mailer.setBody('Bla, bla, bla')mailer.setHeaders(spam: 'no', important: true)

Page 107: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

DSLs: Domain Specific Languages

def mailer = new Mailer()mailer.setTo('[email protected]', '[email protected]')mailer.setSubject('Urgente!')mailer.setBody('Bla, bla, bla')mailer.setHeaders(spam: 'no', important: true)

def mailer = new Mailer() .setTo('[email protected]', '[email protected]') .setSubject('Urgente!') .setBody('Bla, bla, bla') .setHeaders(spam: 'no', important: true)

Page 108: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

DSLs: Domain Specific Languagesmail { to '[email protected]', '[email protected]' subject 'Urgente!' body 'Bla, bla, bla' headers spam: 'no', important: true}

class MailComposer { void to(String... addresses) { println "to: $addresses"} void subject(String subject) { println "subject: $subject" } void body(String body) { println "body: $body" } void headers(Map headers) { println "headers: $headers" }}

void mail(@DelegatesTo(MailComposer) Closure composer) { // Igual que: // new MailComposer().with(composer) Closure cl = composer.clone() cl.delegate = new MailComposer() cl.resolveStrategy = Closure.DELEGATE_FIRST cl()}

Page 109: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

DSLs: Domain Specific Languagesmail { to '[email protected]', '[email protected]' subject 'Urgente!' body 'Bla, bla, bla' headers spam: 'no', important: true}

class MailComposer { void to(String... addresses) { println "to: $addresses"} void subject(String subject) { println "subject: $subject" } void body(String body) { println "body: $body" } void headers(Map headers) { println "headers: $headers" }}

void mail(@DelegatesTo(MailComposer) Closure composer) { // Igual que: // new MailComposer().with(composer) Closure cl = composer.clone() cl.delegate = new MailComposer() cl.resolveStrategy = Closure.DELEGATE_FIRST cl()}

Page 110: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

DSLs: Domain Specific Languagesmail { to '[email protected]', '[email protected]' subject 'Urgente!' body 'Bla, bla, bla' headers spam: 'no', important: true}

class MailComposer { void to(String... addresses) { println "to: $addresses"} void subject(String subject) { println "subject: $subject" } void body(String body) { println "body: $body" } void headers(Map headers) { println "headers: $headers" }}

void mail(@DelegatesTo(MailComposer) Closure composer) { // Igual que: // new MailComposer().with(composer) Closure cl = composer.clone() cl.delegate = new MailComposer() cl.resolveStrategy = Closure.DELEGATE_FIRST cl()}

Page 111: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

➢ +50 trasformación out-of-the-box

➢ @ToString, @EqualsAndHashCode, @InheritConstructors,

@Sortable, @Delegate, @Immutable, @CompileStatic,...

Transformaciones AST

Page 112: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

@EqualsAndHashCodepublic class User extends java.lang.Object {

private java.lang.String name private java.lang.Integer age

public int hashCode() { java.lang.Object _result = org.codehaus.groovy.util.HashCodeHelper.initHash() if (!(this.getName().is(this))) { _result = org.codehaus.groovy.util.HashCodeHelper.updateHash(_result, this.getName()) } if (!(this.getAge().is(this))) { _result = org.codehaus.groovy.util.HashCodeHelper.updateHash(_result, this.getAge()) } return _result }

public boolean canEqual(java.lang.Object other) { return other instanceof User }

public boolean equals(java.lang.Object other) { if ( other == null) { return false } if (this.is(other)) { return true } if (!( other instanceof User)) { return false } User otherTyped = (( other ) as User) if (!(otherTyped.canEqual( this ))) { return false } if (!(this.getName() == otherTyped.getName())) { return false } if (!(this.getAge() == otherTyped.getAge())) { return false } return true }}

Page 113: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

@EqualsAndHashCode

@groovy.transform.EqualsAndHashCodeclass User { String name Integer age}

Page 114: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

¡Gracias!

Page 115: T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

¡Gracias!¿Preguntas?

@ilopmar

[email protected]

https://github.com/ilopmar

Iván López

http://bit.ly/t3chfest-groovy