• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Groovy & Grails
 

Groovy & Grails

on

  • 2,706 views

Presentazione introduttiva su Groovy e Grails tratta dal materiale della serie di eventi Into The Groovy del JUG Milano tenuta allo Spring Meeting del 26/06/2010 a Cagliari organizzato da JUG Sardegna ...

Presentazione introduttiva su Groovy e Grails tratta dal materiale della serie di eventi Into The Groovy del JUG Milano tenuta allo Spring Meeting del 26/06/2010 a Cagliari organizzato da JUG Sardegna http://www.jugsardegna.org/vqwiki/jsp/Wiki?26giugno2010

Statistics

Views

Total Views
2,706
Views on SlideShare
2,579
Embed Views
127

Actions

Likes
1
Downloads
17
Comments
0

8 Embeds 127

http://www.jroller.com 56
http://www.jugsardegna.org 31
http://desmax74.wordpress.com 25
http://jroller.com 9
http://translate.googleusercontent.com 2
http://www.slashdocs.com 2
http://www.directrss.co.il 1
http://www.linkedin.com 1
More...

Accessibility

Upload Details

Uploaded via as Adobe PDF

Usage Rights

CC Attribution-NonCommercial-ShareAlike LicenseCC Attribution-NonCommercial-ShareAlike LicenseCC Attribution-NonCommercial-ShareAlike License

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Groovy & Grails Groovy & Grails Presentation Transcript

    • Groovy & Grails Marcello Teodori marcello.teodori@jugmilano.it Java User Group Milano http://www.jugmilano.it Spring Meeting Giugno 2010 - Cagliari
    • Di cosa parleremo? ● what is Groovy? ● in viaggio da Java a Groovy, levando un pezzo alla volta ● cosa c'è di nuovo in Groovy ● Groovy e testing ● Groovy e Spring ● Grails Spring Meeting Giugno 2010 2
    • Due parole sullo speaker ● Coordinatore del JUG Milano ● Moderatore SpringFramework-IT ● Moderatore Gruppo Italiano Utenti Groovy ● Socio e CTO in ExcogitaNet ● più twitterer: http://twitter.com/magomarcelo che blogger: http://magomarcelo.blogspot.com ● Speaker ad All4Web, evento RIA cross-community ● Organizzatore di Into The Groovy, ciclo di eventi e workshop del JUG Milano in collaborazione con BYTE-CODE Spring Meeting Giugno 2010 3
    • Partiamo dallo stato delle cose... Spring Meeting Giugno 2010 4
    • Cosa è Groovy? ● Groovy è un linguaggio dinamico per la Java Virtual Machine (JVM) ● si ispira a Smalltalk, Python e Ruby ● ma soprattutto... si integra con il linguaggio e la piattaforma Java a tutti i livelli Spring Meeting Giugno 2010 5
    • Un po' di storia di Groovy ● nasce nel 2003 come progetto personale di James Strachan: “a groovier Java” http://radio.weblogs.com/0112098/2003/08/29.html ● JSR-241, poi bug, rallentamenti e disinteresse ● Guillame LaForge riprende il progetto nel 2005 ● sempre nel 2005 Graeme Rocher crea Grails ● nel 2007 LaForge e Rocher fondano G2One ● G2One viene acquisita da SpringSource a fine 2008 Spring Meeting Giugno 2010 6
    • Groovy Tools Installato Groovy sul nostro sistema (via uncompress più aggiunta directory “bin” al PATH di sistema), unico prerequisito il JDK 1.4+, abbiamo a nostra disposizione: ● groovy – l'interprete Groovy ● groovyc – il compilatore Groovy/Java ● groovysh – la CUI shell interattiva ● groovyConsole – la GUI shell ● groovy-all-*.jar – runtime JAR ● java2groovy – il “facilitatore” ;) Spring Meeting Giugno 2010 7
    • Groovy OOP In Groovy tutto è un oggetto (a differenza di Java che ha i tipi primitivi) In Java, prima delle funzionalità di boxing/unboxing si dovevano per forza usare i wrapper type come ponte tra i tipi primitivi e gli oggetti. Inoltre, nessun reference type può essere impiegato come operando per operatori come +,*,- Esiste quindi una precisa dicotomia in Java tra reference e tipi primitivi. Questo porta alla scrittura di codice eccessivamente prolisso, nonostante le migliorie apportate da Java 5 in poi. Ad esempio: for (int i=0; i < listOne.size(); i++) int first = listOne.get(i); int second = listTwo.get(i); int sum = first + second; results.add (new Integer(sum)); Spring Meeting Giugno 2010 8
    • Operator Overloading In Groovy avremmo potuto scrivere molto + semplicemente results.add (first.plus(second)) Sfruttando il fatto che in Groovy è stato aggiunto ad Integer il metodo plus. In realtà possiamo fare molto di più, grazie alla possibilità di effettuare in Groovy l'overloading degli operatori, che possono in tal modo operare direttamente su reference ad oggetti e non solo su tipi primitivi. results.add (first + second) Si può usare questa sintassi proprio perché in Integer è stato effettuato l'overloading di tutti gli operatori. Immaginiamo adesso di voler introdurre un nuovo tipo (classe) che possa essere usato come operando da + ed == Tutto quello che dobbiamo fare è definire due metodi, plus ed equals, non occorre implementare nessuna interfaccia particolare. Spring Meeting Giugno 2010 9
    • Operator Overloading class Money { private int amount private String currency boolean equals (Object other) { if (null == other) return false if (! (other instanceof Money)) return false if (currency != other.currency) return false if (amount != other.amount) return false return true } Money plus (Money other) { if (null == other) return null if (other.currency != currency) { throw new IllegalArgumentException( "cannot add $other.currency to $currency") } return new Money(amount + other.amount, currency) } Spring Meeting Giugno 2010 10
    • Operator Overloading Avendo ridefinito gli operatori in tal modo, adesso i reference a Money possono essere usati direttamente come operandi. def oneEuro = new Money(1, 'EUR') assert oneEuro == new Money(1, 'EUR') assert oneEuro + oneEuro == new Money(2, 'EUR') È possibile fornire più di una versione dello stesso operatore Ad esempio: Money plus (Integer more) { return new Money(amount + more, currency) } Adesso potremmo scrivere new Money(1, 'EUR') + 5 L'operatore (metodo) corretto sarà individuato da Groovy a runtime Spring Meeting Giugno 2010 11
    • Optional Typing Differentemente che in Java, in Groovy non è obbligatorio specificare il tipo statico di una qualsiasi variabile In realtà, dietro le quinte, tutto diventa in Groovy un java.lang.Object La keyword def è usata per indicare che non si vuole usare uno specifico tipo statico. def a = 1 def b = 1.0f // implicit typing int i = 2 // explicit typing Integer i2 = 3 È importante capire che Groovy è type-safe, anche se si usa l'optional typing. A differenza di linguaggi non tipizzati, Groovy non consente di trattare un'istanza di un tipo come se fosse un'istanza di un differente tipo, senza una conversione disponibile. Ad esempio non sarebbe possibile assolutamente trattare la stringa “1” come se fosse un numero all'interno di un'operazione aritmetica. Spring Meeting Giugno 2010 12
    • Groovy OOP La definizione di una classe in Groovy è molto simile a quanto si fa in Java, con alcune lievi differenze in un singolo file .groovy è anzitutto possibile definire quante public class si desiderano, non soltanto una, I modificatori di accesso (private, protected, public, static e final) hanno lo stesso significato di Java Una variabile d'istanza al livello di visibilità default è in realtà una property. Definire il tipo di una qualsiasi variabile d'istanza è opzionale. class SomeClass { //instance var public fieldWithModifier String typedField def untypedField protected field1, field2, field3 private assignedField = new Date() static classField def someMethod() { //local var def localUntypedMethodVar = 1 int localTypedMethodVar = 1 def localVarWithoutAssignment, andAnotherOne } } Spring Meeting Giugno 2010 13
    • Groovy OOP L'accesso alle variabili d'istanza può avvenire attraverso la consueta notazione con il punto: class MyClass { public myField = 0 } def myInstance = new MyClass() myInstance.myField = 1 assert myInstance.count == 1 Tuttavia è disponibile anche un modo più dinamico di accedere le variabili di istanza, attraverso l'operatore subscript def fieldName = 'myField' myInstance [fieldName] = 2 assert myInstance['myField'] == 2 Spring Meeting Giugno 2010 14
    • Groovy OOP Anche nella definizione dei metodi valgono ragionamenti analoghi a quanto visto per le variabili d'istanza. Il modificatore di accesso di default è public. Il tipo di ritorno, incluso void, è opzionale. Tuttavia, se non si specifica né il tipo di ritorno né un modificatore di accesso, è obbligatorio usare la keyword def (vale anche per i field). Di seguito un esempio: class AClass { static void main(args) { def aClass = new AClass() aClass.publicVoid() assert 'A' == aClass.publicNoType() assert 'B' == aClass.publicWithType() } void publicVoid() { } def publicNoType() { return 'A' } String publicWithType() { return 'B' } } Spring Meeting Giugno 2010 15
    • Groovy OOP Per definire i parametri formali di un metodo, Groovy offre ben quattro approcci differenti, evidenziati nell'esempio seguente. class ManyMethodsClass { def firstApproach ( a, b, c = 0 ) { return a + b + c } def secondApproach ( List args ) { return args.inject(0) { sum,i -> sum += i } } def thirdApproach ( a, b, Object[] optionals ) { return a + b + secondApproach ( optionals.toList() ) } def fourthApproach ( Map args ) { [ 'a', 'b', 'c']. each { args.get(it,0) } return args.a + args.b + args.c } } Spring Meeting Giugno 2010 16
    • Groovy OOP E di seguito un esempio di invocazione dei vari metodi def instance = new ManyMethodsClass() assert 2 == instance.firstApproach(1,1) assert 3 == instance.firstApproach(1,1,1) assert 2 == instance.secondApproach ( [1,1] ) assert 3 == instance.secondApproach ( [1,1,1] ) assert 2 == instance.thirthApproach ( 1,1 ) assert 3 == instance.thirthApproach ( 1,1,1 ) assert 2 == instance.fourthApproach( a:1, b:1) assert 3 == instance.fourthApproach( a:1, b:1, c:1) assert 1 == instance.fourthApproach( c:1 ) L'ultimo caso dettaglia l'utilizzo della tecnica di passaggio dei parametri per nome anzichè posizionale. Spring Meeting Giugno 2010 17
    • Groovy OOP Come in Java, anche in Groovy le istanze vengono inizializzate a partire da un costruttore. Nel realizzare i costruttori si può trarre beneficio dalle tecniche viste nel passaggio dei parametri ai metodi. La forma più familiare di costruttore è la seguente class Aclass { String first, second; Aclass (first, second) { this.first = first this.second = second } } Un oggetto di tale classe può essere istranziato in tre modi diversi: 1) def instance = new Aclass (“value1”, “value2”) 2) def instance = [ “value1”, “value2” ] as Aclass // coercion con as 3) Aclass instance = [ ”value1”, ”value2” ] // coercion in assegnamento Spring Meeting Giugno 2010 18
    • Groovy OOP Se non si vuole definire esplicitamente un costruttore, è possibile sfruttare anche in fase di istanziazione la flessibilità dei named parameters. class Aclass { String first, second; } new Aclass() new Aclass ( first: 'value' ) new Aclass ( second: 'value' ) new Aclass ( first: 'value', second: 'value' ) Spring Meeting Giugno 2010 19
    • POJO vs. POGO Java Groovy package it.jug...odel; package it.jug...odel; public class Product { class Product { private Integer id; Integer id private String name; String name public Long getId() { String toString() { return id; name } } } public void setId(Long id) { this.id = id; } ... public String toString() { return name; } } Spring Meeting Giugno 2010 20
    • Groovy OOP - multimethod In Java il processo di linking dei metodi ha regole ben precise: La firma esatta del metodo da invocare viene effettuata sulla base del tipo dinamico del reference e del tipo statico dei parametri. public class Parent { public void method (Object o) { System.out.println("Object in Parent"); } public void method (String s) { System.out.println("String in Parent" ); } } public class Child { public void method (Object o) { System.out.println("Object in Child"); } public void method (String s) { System.out.println("String in Child" ); } public static void main(String[] a){ Parent child = new Child(); child.method("ciao"); // stampa ”String in child” Object oo = "bau"; child.method(oo); // stampa ”Object in child” } In Groovy, al contrario, nel decidere il metodo da invocare, viene usato il tipo dinamico anche dei parametri. Il codice Groovy equivalente invocherebbe 2 volte il metodo della sottoclasse che riceve stringhe. Spring Meeting Giugno 2010 21
    • Collection - Range Pensiamo a quante volte in Java ci si trova a scrivere codice come il seguente: for (int i=0; i<upperBound; i++) { // do something with i } oppure if (x >= 0 && x <= upperBound) { // do something with x } Non è difficilissimo da capire, ma potrebbe essere scritto in maniera più semplice e soprattutto più espressiva Per questo motivo è stato inserito nativamente in Groovy il concetto di Range: un range ha un left bound ed un right bound. È possibile specificare una qualsiasi azione per ogni elemento di un Range. Spring Meeting Giugno 2010 22
    • Collection - Range In definitiva: un Range è un intervallo associato ad una strategia per interagire con i suoi elementi Un Range può essere istanziato tramite la notazione .. o attraverso l'uso esplicito di un costruttore assert (0..10).contains(0) assert (0..10).contains(10) // true, estremi inclusi assert (0..10).contains(12) // false def a = 0..10 assert a instanceof Range assert a.contains(5) a = new IntRange (0,10) assert a.contains (5) def today = new Date() def yesterday = today-1 assert (yesterday..today).size() == 2 Spring Meeting Giugno 2010 23
    • Collection - Range Un Range è un oggetto di classe groovy.lang.Range che espone una serie di metodi di utilità. Quelli di utillizo più comune sono each: esegue una specifica closure per ogni elemento del range contains: determina se un elemento fa parte o meno di un range Ad esempio: result = '' (5..9).each { element -> result += element } println result assert result == '56789' Spring Meeting Giugno 2010 24
    • Collection - List Le liste in Groovy uniscono la versatilità e semplicità degli array alla dinamicità di java.util.List. Dichiarare una lista in Groovy è banale: implicitList = [1,2,3] assert myList.size() == 3 assert myList[0] == 1 assert myList instanceof ArrayList Oppure explicitList = new ArrayList() explicitList.addAll(implicitList) assert explicitList.size() == 3 explicitList[0] = 10 assert explicitList[0] == 10 explicitList = new LinkedList(implicitList) assert explicitList.size() == 3 È anche possibile costruire una Lista a partire da un Range longList = (0..1000).toList() assert longList[555] == 555 Spring Meeting Giugno 2010 25
    • Collection - List L'utilizzo combinato di liste ed overloading degli operatori rende la scrittura di codice che gestisce collezioni indexed estremamente semplice e compatto. myList = ['a','b','c','d','e','f'] assert myList[0..2] == ['a','b','c'] // getAt (range) assert myList[0,2,4] == ['a','c','e'] // getAt (collection indexed) myList[0..2] = ['x','y','z'] // putA assert myList == ['x','y','z','d','e','f'] myList[3..5] = [] assert myList == ['x','y','z'] myList[1..1] = ['y','1','2'] assert myList == ['x','y','1','2','z'] Oltre all'operatore equals nel codice sopra è visibile l'uso anche dell'operatore subscript, implementato tramite la coppia di metodi getAt e putAt Spring Meeting Giugno 2010 26
    • Collection - List Oltre agli operatori di subscripting, sono disponibili anche gli operatori + (plus), - (minus), * (multiply), << (leftshift) Essi operano nel modo seguente: MyList = [ ] myList += 'a' assert myList == ['a'] myList += ['b','c'] assert myList == ['a','b','c'] MyList = [ ] myList << 'a' << 'b' assert myList == ['a','b'] assert myList - ['b'] == ['a'] assert myList * 2 == ['a','b','a','b'] Spring Meeting Giugno 2010 27
    • Collection - List L'interfaccia List in Groovy aggiunge un ricco insieme di metodi alle già ricche funzionalità presenti in Java. assert [1,[2,3]].flatten() == [1,2,3] assert [1,2,3].intersect([4,3,1])== [3,1] list = [1,2,3] popped = list.pop() assert popped == 3 assert list == [1,2] assert [1,2].reverse() == [2,1] assert [3,1,2].sort() == [1,2,3] assert list == [ [1,0], [0,1,2] ] list = ['a','b','c'] list.remove(2) assert list == ['a','b'] list.remove('b') assert list == ['a'] Spring Meeting Giugno 2010 28
    • Collection - Map La creazione di oggetti con interfaccia Map in Groovy gode di analoga semplificazione: la Map per Groovy è una List con indici non Integer. def map = [a: 1, b: 2, b: 3] assert map.a == 1 assert map['a'] == 1 assert map.get('d', 'pippo') == 'pippo' map.d = 'pippo' assert map['d'] == 'pippo' for (entry in map) { println “$entry.key = $entry.value” } map.each { entry → println “$entry.key = $entry.value” } map.each { key, value → println “$key = $value” } Spring Meeting Giugno 2010 29
    • Closure Le closure sono uno degli elementi che aumentano maggiormente l'espressività di Groovy. Mentre in un linguaggio tradizionale nelle variabili possono essere salvati esclusivamente dati, un linguaggio che supporta le closure consente di salvare in una variabile dati e codice. Questo consente di creare algoritmi complessi con una sintassi molto semplice Semplificando molto, una closure può essere pensata come uno speciale costrutto per passare un blocco di codice come argomento di un metodo. In pratica una closure è un oggetto contenente un blocco di codice. Ad esempio, la seguente è la più semplice (ed in realtà inutile) forma di closure def closure = { println "sono una closure!" } closure() // stampa "sono una closure!" Ad una closure è possibile passare dei parametri attraverso l'operatore - > def closure = {x,y,z - > print x + y + z} closure (1,2,3) //stampa 6 Spring Meeting Giugno 2010 30
    • Closure Se la closure riceve un unico parametro, è possibile ometterlo nella definizione e riferirlo con la variabile speciale it. def clos = { print it } clos( "parametro implicito" ) Le due forme seguenti di esprimere una closure sono perfettamente equivalenti: def square = { operand - > operand * operand} def square = { it * it } L'aspetto più interessante delle closure è che possono essere passate ad un qualsiasi metodo che la definisca tra i propri parametri formali. Ad esempio, il metodo collect di Collection in Groovy ha la seguente definizione List collect(Closure closure) ed è pensato per iterare tutti gli elementi della Collection, applicando la funzione passata nella closure e restituendo una nuova lista costruita con tali elementi. Spring Meeting Giugno 2010 31
    • Closure – collection projection Se volessimo una lista contenente il doppio di ciascun elemento presente in una lista di partenza, sarebbe sufficiente scrivere def list = [2,3,4] def newList = [ ] newList = list.collect { it*2 } Questo consente di scrivere codice estremamente compatto ed espressivo Ad esempio, data la definizione class Employee { def salary } Grazie alle closure, possiamo costruire una Lista di Employee a partire da un Range di numeri in un'unica linea di codice, senza nemmeno un'iterazione def emps = [10, 20, 30]. collect { val -> new Employee(salary:val) } Spring Meeting Giugno 2010 32
    • Closure – collection filtering E se volessivo una List di tutti gli employee che guadagnano tra 10000 e 20000? Potremmo sfruttare il metodo definito nelle Collection di groovy Collection findAll(Closure closure) che restituisce una collection con solo gli elementi che soddisfano la condizione specificata nella closure. Nel nostro caso avremmo: def interestingEmployees(emps) { def min = 10000 def max = 20000 return emps.findAll { e -> e.salary < max && e.salary > min } } def emps = [10, 20, 30]. collect { val -> new Employee(salary:val) } Collection c = interestingEmployees ( emps ) Spring Meeting Giugno 2010 33
    • Reflection in Groovy In Java sin dalle prime versioni sono disponibili tecniche molto avanzate di programmazione dinamica, attraverso l'uso delle Reflection API. In Groovy questo concetto è ulteriormente potenziato e, soprattutto, reso molto più semplice da utilizzare. Ad esempio, è possibile invocare un metodo su un'istanza di classe SENZA specificare il nome del metodo a tempo di compilazione: class Cane extends Animale { void corri () { println("sto correndo") } void mangia (cibo) { println "sto mangiando " + cibo } } def someMethodInSomeClass (animale, nomeMetodo, Object[] params) { animale."$nomeMetodo"(*params) } someMethodInSomeClass (new Cane(), "corri") someMethodInSomeClass (new Cane(), "mangia" , "erba") Un codice equivalente in Java sarebbe molto più lungo e complesso. Spring Meeting Giugno 2010 34
    • ed ora uso Groovy al posto di Java! paura eh? Spring Meeting Giugno 2010 35
    • Groovy senza paura! ● scripting e codice di supporto ● unit testing – GroovyTestCase per JUnit 3 – JUnit 4 annotation su classi Groovy ● mocking tramite supporto dynamic languages di Spring con <lang:groovy../> ● progettazione domain model ● prototipazione rapida Spring Meeting Giugno 2010 36
    • Grails come Groovy on Rails! RAD per applicazioni web domain-driven basato su convention over configuration ● Spring MVC in disguise ● DSL – BeanBuilder per Spring – GORM per Hibernate ● shell per automatizzare operazioni ● plugin system – directory con ampia scelta – community molto attiva Spring Meeting Giugno 2010 37
    • Demo CRUD webapp Team/Players tratto da presentazione di Davide Rossi al JUG Milano, 22/01/2009 ● Create a new application ● Create domain classes – Datasource – Constraints – Associations ● Create controllers / views ● Run the application ● Searching – Dynamic finders – HQL (Hibernate query language) – Hibernate Criteria ● Pagination Spring Meeting Giugno 2010 38
    • Conclusioni ● Java è così vecchio? Mettiamo Groovy al posto di Java come linguaggio principale della JVM! ● Groovy e tecnologie correlate hanno un approccio in stile “standing on the shoulders of giants”, cioè che costruisce “sulle spalle dei giganti”: Java, Spring, Hibernate, ecc. ● groovySpeed = JavaSpeed / 15 ma la velocità è così importante? ● invokedynamic in Java 7 ● attenzione ad un uso “consapevole” di Groovy! ● codice di prototipo, produzione, supporto o testing... c'è sempre un posto in cui Groovy può essere utile! Spring Meeting Giugno 2010 39
    • Riferimenti ● Groovy http://groovy.codehaus.org/ ● Grails http://www.grails.org/ ● JUG Milano – Into The Groovy http://www.jugmilano.it/vqwiki/jsp/Wiki?IntoTheGroovy Spring Meeting Giugno 2010 40
    • Q&A Spring Meeting Giugno 2010 41