View
2.801
Download
2
Embed Size (px)
DESCRIPTION
Citation preview
Alberto Brandolini - [email protected] – Grails-ITJavaday Roma III Edizione – 24 gennaio 2009
Enterprise-class DSLs in
Groovy & Grails
1
Alberto Brandolini - [email protected] – Grails-ITJavaday Roma III Edizione – 24 gennaio 2009
About me
Strategic IT consultantTrainer
- Skills Matter, ...Articoli
- Mokabyte, …Blogger
- Ziobrando’s Lair“animatore” di Community
- Grails-IT- DDD-IT
2
Alberto Brandolini - [email protected] – Grails-ITJavaday Roma III Edizione – 24 gennaio 2009
A cosa serve un DSL?
Un DSL è uno strumento per la condivisione di informazioni specializzato per uno specifico contesto
- dominio del problema- ruoli coinvolti- ambito di applicazione
- Facilita la condivisione di informazioni (precise e prive di ambiguità) all’interno di un gruppo
- si tratta di uno strumento per migliorare l’efficienza della comunicazione
3
Mettere la foto di un addetto all’atterraggio
Alberto Brandolini - [email protected] – Grails-ITJavaday Roma III Edizione – 24 gennaio 2009
… un classico esempio di DSL
4
Alberto Brandolini - [email protected] – Grails-ITJavaday Roma III Edizione – 24 gennaio 2009
5Un Domain Specific Language nasce per coprire un’esigenza di comunicazione in un contesto specifico indirizzando alcuni elementi della comunicazione: l’impossibilità di utilizzare determinati canali (in questo caso l’audio), la necessità di comunicare con maggiore rapidità e precisione, la necessità di essere sintetici
Alberto Brandolini - [email protected] – Grails-ITJavaday Roma III Edizione – 24 gennaio 2009
Ecosistema di progetto
6
Specification
Code
Domain Expert
Analyst
Architect Tester
Developer DBA
Un DSL è comunque uno strumento di comunicazione: perchè sia efficace la comunicazione deve coinvolgere almeno due soggetti che condividano informazioni.
In un classico contesto di progetto sono presenti diversi ruoli che fanno uso d diversi linguaggi. Esistono DSL specificati per determinati compiti, ma ciò che può avere impatto sul nostro modo di produrre software è rappresentato dal DSL specifico del dominio applicativo, ovvero della lingua parlata dall’esperto di dominio.
Alberto Brandolini - [email protected] – Grails-ITJavaday Roma III Edizione – 24 gennaio 2009
Ecosistema di progetto
6
Specification
Code
Domain Expert
Analyst
Architect Tester
Developer DBA
DSL
Un DSL è comunque uno strumento di comunicazione: perchè sia efficace la comunicazione deve coinvolgere almeno due soggetti che condividano informazioni.
In un classico contesto di progetto sono presenti diversi ruoli che fanno uso d diversi linguaggi. Esistono DSL specificati per determinati compiti, ma ciò che può avere impatto sul nostro modo di produrre software è rappresentato dal DSL specifico del dominio applicativo, ovvero della lingua parlata dall’esperto di dominio.
Alberto Brandolini - [email protected] – Grails-ITJavaday Roma III Edizione – 24 gennaio 2009
Ecosistema di progetto
6
Specification
Code
Domain Expert
Analyst
Architect Tester
Developer DBA
DSL ?
Un DSL è comunque uno strumento di comunicazione: perchè sia efficace la comunicazione deve coinvolgere almeno due soggetti che condividano informazioni.
In un classico contesto di progetto sono presenti diversi ruoli che fanno uso d diversi linguaggi. Esistono DSL specificati per determinati compiti, ma ciò che può avere impatto sul nostro modo di produrre software è rappresentato dal DSL specifico del dominio applicativo, ovvero della lingua parlata dall’esperto di dominio.
Alberto Brandolini - [email protected] – Grails-ITJavaday Roma III Edizione – 24 gennaio 2009
Ecosistema di progetto
6
Specification
Code
Domain Expert
Analyst
Architect Tester
Developer DBA
DSL ?
UML
Un DSL è comunque uno strumento di comunicazione: perchè sia efficace la comunicazione deve coinvolgere almeno due soggetti che condividano informazioni.
In un classico contesto di progetto sono presenti diversi ruoli che fanno uso d diversi linguaggi. Esistono DSL specificati per determinati compiti, ma ciò che può avere impatto sul nostro modo di produrre software è rappresentato dal DSL specifico del dominio applicativo, ovvero della lingua parlata dall’esperto di dominio.
Alberto Brandolini - [email protected] – Grails-ITJavaday Roma III Edizione – 24 gennaio 2009
Ecosistema di progetto
6
Specification
Code
Domain Expert
Analyst
Architect Tester
Developer DBA
DSL ?
UML
Java
Un DSL è comunque uno strumento di comunicazione: perchè sia efficace la comunicazione deve coinvolgere almeno due soggetti che condividano informazioni.
In un classico contesto di progetto sono presenti diversi ruoli che fanno uso d diversi linguaggi. Esistono DSL specificati per determinati compiti, ma ciò che può avere impatto sul nostro modo di produrre software è rappresentato dal DSL specifico del dominio applicativo, ovvero della lingua parlata dall’esperto di dominio.
Alberto Brandolini - [email protected] – Grails-ITJavaday Roma III Edizione – 24 gennaio 2009
Ecosistema di progetto
6
Specification
Code
Domain Expert
Analyst
Architect Tester
Developer DBA
DSL ?
UML
Java
Java
Un DSL è comunque uno strumento di comunicazione: perchè sia efficace la comunicazione deve coinvolgere almeno due soggetti che condividano informazioni.
In un classico contesto di progetto sono presenti diversi ruoli che fanno uso d diversi linguaggi. Esistono DSL specificati per determinati compiti, ma ciò che può avere impatto sul nostro modo di produrre software è rappresentato dal DSL specifico del dominio applicativo, ovvero della lingua parlata dall’esperto di dominio.
Alberto Brandolini - [email protected] – Grails-ITJavaday Roma III Edizione – 24 gennaio 2009
Ecosistema di progetto
6
Specification
Code
Domain Expert
Analyst
Architect Tester
Developer DBA
DSL ?
UML
Java
Java
SQL
Un DSL è comunque uno strumento di comunicazione: perchè sia efficace la comunicazione deve coinvolgere almeno due soggetti che condividano informazioni.
In un classico contesto di progetto sono presenti diversi ruoli che fanno uso d diversi linguaggi. Esistono DSL specificati per determinati compiti, ma ciò che può avere impatto sul nostro modo di produrre software è rappresentato dal DSL specifico del dominio applicativo, ovvero della lingua parlata dall’esperto di dominio.
Alberto Brandolini - [email protected] – Grails-ITJavaday Roma III Edizione – 24 gennaio 2009
Avviciniamo i contesti
7
Specification
Code
Domain Expert
Analyst
ArchitectTester
Developer DBA
Potendo intervenire sulla forma dell’applicazione e sulla lingua utilizzata al suo interno, possiamo avvicinare mondi diversi. Possiamo avere maggiore controllo sulla corrispondenza tra il codice applicativo e le specifiche e ridurre molto del fardello di overhead e sincronizzazione legato alla presenza di due “viste” sulla stessa applicazione.
Alberto Brandolini - [email protected] – Grails-ITJavaday Roma III Edizione – 24 gennaio 2009
Avviciniamo i contesti
7
Specification
Code
Domain Expert
Analyst
ArchitectTester
Developer DBA
qui può succedere qualcosa di interessante
Potendo intervenire sulla forma dell’applicazione e sulla lingua utilizzata al suo interno, possiamo avvicinare mondi diversi. Possiamo avere maggiore controllo sulla corrispondenza tra il codice applicativo e le specifiche e ridurre molto del fardello di overhead e sincronizzazione legato alla presenza di due “viste” sulla stessa applicazione.
Alberto Brandolini - [email protected] – Grails-ITJavaday Roma III Edizione – 24 gennaio 2009
DSL in Enterprise Application
...scrivere codice che si possa leggere e capire a colpo d’occhio.
A chi giova?- codice applicativo più conciso e self-explaining- possibilità di controllare la più rapidamente la
correttezza e/o la corrispondenza alle specifiche- scrittura di test più veloce- scrittura di test allargata a ruoli tradizionalmente
esclusi
8Quindi è interessante notare che il focus si sposta sul codice di test: abbiamo qualche vantaggio significativo a livello di codice applicativo, che risulta più leggibile e privo di fronzoli (basti pensare alle acrobazie necessarie per gestire i BigDecimal o le Date.
Alberto Brandolini - [email protected] – Grails-ITJavaday Roma III Edizione – 24 gennaio 2009
Different approcci ali DSL
Vari approcci al problema:Parser/interpreti interni all’applicazioneScrittura di codice self-explaining
Domain Driven Design, fluent interfaces
Generazione specializzata di codice applicativoIntentional Software, MDA, …
…Espansione delle possibilità espressive del linguaggio
C++, Groovy, ...
9Dove l’esigenza di conformarsi ad un SL già esistente era particolarmente forte, si è fatto ricorso ad interpreti/parser dedicati, che permettessero l’uso del DSL nelle applicazioni.Altri tentativi sono stati legati alla possibilità di rendere il codice più accessibile, ma la verbosità tecnologica di Java ha ostacolato questa direzione.Un’altra strada è quella legata alla generazione di codice a partire da una specifica espressa in una sorta di DSL (quindi realizzando l’applicazione in due fasi) separate.Infine (ed è la zona in cui si colloca Groovy) c’è la possibilità di allargare le possibilità espressive del linguaggio stesso, sfruttandone le possibilità di espansione.
Alberto Brandolini - [email protected] – Grails-ITJavaday Roma III Edizione – 24 gennaio 2009
DSL in Groovy
Groovy introduce nuovi strumenti che aprono scenari sulla JVM:
- overloading degli operatori- object orientation completa- coercition dei tipi numerici- risoluzione dinamica dei metodi- strumenti di metaprogrammazione- … piccole “chicche” sparse qua e la.
10Groovy in questo senso rappresenta un passo in avanti notevole rispetto a Java, la cui struttura non era sufficientemente flessibile.Matte infatti a disposizione una serie di strumenti legati alle sue caratteristiche di linguaggio dinamico che permettono di raggiungere risultati interessanti, senza arrivare alla complicazione di un parser dedicato.
Alberto Brandolini - [email protected] – Grails-ITJavaday Roma III Edizione – 24 gennaio 2009
Money: obiettivi
Vogliamo esplorare le possibilità di scrittura di queste componenti offerte da Groovy
Approccio white-box, partendo dal foglio bianco (?)
11
- Domain Class in Groovy
- Value Object riutilizzabile
- Aritmetica Domain Specific
Come primo esempio delle possibilità offerte da Groovy, esaminiamo la possibilità di definire un piccolo dialetto legato alle operazioni finanziarie, gestendo quindi una “tipica” classe Money
Alberto Brandolini - [email protected] – Grails-ITJavaday Roma III Edizione – 24 gennaio 2009
DDD Value Object
In Domain Driven Design un Value Object è un oggetto caratteristico del dominio applicativo:immutabilecondivisibileprivo di identità specifica
La presenza dei Value Object è un elemento caratterizzante dei Rich Domain Model
12Money, rappresenta un classico esempio di Value Object, secondo la classificazione di DDD.Non c’è una corrispondenza precisa tra VO e DSL, i due concetti sono in larga parte ortogonali, tuttavia buona parte dei DSL “general purpose” quindi legati a più domini applicativi sono basati su concetti che ricadono in questa categoria. Gli strumenti offerti da Groovy al riguardo, rendono estremamente conveniente affrontare il problema in quest’ottica.
Alberto Brandolini - [email protected] – Grails-ITJavaday Roma III Edizione – 24 gennaio 2009
Time and Money
Libreria Java open source “emanazione” di Domain Driven Design
Tipi di dato riutilizzabili in svariati dominiialcuni problemi ricorrenti già affrontati:
precisione del calcolo finanziario,usabilità delle datepersistenza dei tipi di dato
Maggiore espressività e chiarezza
13Come esempio di riferimento prendiamo quindi l’implementazione di Money, definita dalla libreria Time and Money, con l’obiettivo di verificare costi e benefici di una “riscrittura” in Groovy
Alberto Brandolini - [email protected] – Grails-ITJavaday Roma III Edizione – 24 gennaio 2009
Java “blocca la strada”
BigDecimal non è un tipo numerico primitivoOperatori aritmetici da ridefinireCambiamento di tipo tutt’altro che fluidoComportamento non sempre “user friendly”
java.lang.AssertionError:expected:<EUR4>butwas:<EUR4.0000000000000002220446049250313080847263336181640625>
Come sono arrivato a questa situazione?
14La scrittura di una componente relativamente semplice, ha però in Java qualche complicazione in più del previsto, legata al fatto che BigDecimal NON è un tipo primitivo, quindi anche l’autoboxing di java 5 non ci aiuta più di tanto.
In particolare va rimarcato che BigDecimal ha un comportamento diverso nel caso sia invocato come new BigDecimal(...) rispetto a BigDecimal.valueOf(...) con lo stesso argomento!
Alberto Brandolini - [email protected] – Grails-ITJavaday Roma III Edizione – 24 gennaio 2009
...una buona notizia
La scrittura della classe, a parità di test superati, ha richiesto circa la metà del codice:Sintassi più concisa
gestione dei BigDecimal molto smooth (via coercition)
Alcuni metodi di utilità non più necessari
Zucchero sintattico decisamente demodè
Non solo…l’overloading degli operatori permette di scrivere:
15
Money tenEuros = Money.euros(10)Money twentyEuros = Money.euros(20)assert twentyEuros == tenEuros + tenEurosassert twentyEuros == tenEuros * 2
Tenendo ferme le caratteristiche definite dalla suite di test la scrittura del codice si è rivelata molto più agevole, tanto in lunghezza, che in complessità.
Molti metodi erano relativi a problematiche che in Groovy sono assolte direttamente dalla piattaforma, altre risultano obsolete dalle possibilità offerte dalla meta programmazione. L’overloading degli operatori premette già di trattare Money come un tipo primitivo.
Alberto Brandolini - [email protected] – Grails-ITJavaday Roma III Edizione – 24 gennaio 2009
The comparable bug
Scompaiono anche i problemi nella gestione della precisione… (sembra troppo facile…)
... in effetti era un bugGroovy usa compareTo() dietro le quinte se si
invoca ‘==’ su un Comparable
16
junit.framework.AssertionFailedError:expected:<EUR10>butwas:<EUR10.00>
Qualche piccola sorpresa legata ad un problema “atteso” ma non presentatosi. Si tratta in realtà di un’anomalia “benigna” di Groovy, ma che sarà corretta prima o poi. Nel nostro caso l’implementazione corrente fa al caso nostro, ma dovremo verificare il comportamento con le prossime versioni del linguaggio.
Alberto Brandolini - [email protected] – Grails-ITJavaday Roma III Edizione – 24 gennaio 2009
Money - continued
E’ necessario intervenire più in profondità per rendere la cosa più interessante
Entra in gioco la ExpandoMetaClass
17
- Creazione delle istanze di Money
- reversibilità delle operazioni
… Quanto fato fino adesso è già piuttosto interessante, ma possiamo fare di meglio. la metaprogrammazione in Grovy ci permette di manipolare le classi Java e Groovy, spingendole oltre l’immaginazione dei progettisti originari.
Alberto Brandolini - [email protected] – Grails-ITJavaday Roma III Edizione – 24 gennaio 2009
Expando Meta Class
EMC permette di aggiungere nuovi comportamenti alle classi già esistenti, a run time, senza modificarne il codice
18
plus(...)minus(...)...
Currency currencyBigDecimal amount
� � � � �
multiply(..)getReference()
Currency currencyBigDecimal amount
� � � � �
� � � � � � � � � � � � � �
In particolare ci interesserà l’operatore ‘.’ corrispondente al metodo getReference, che simula l’invocazione di un metodo getter su una property che non esiste nella classe originaria ma che abbiamo definito nella corrispondente MetaClass
Alberto Brandolini - [email protected] – Grails-ITJavaday Roma III Edizione – 24 gennaio 2009
I soldi iniziano a girare...
19
assert 20.EUR == 10.EUR + 10.EUR
assertEquals 45.EUR, 9.EUR * 5assertEquals 45.EUR, 5 * 9.EUR
assertEquals 4.EUR, 36.EUR / 9assertEquals 4, 36.EUR / 9.EUR
assert 4.EUR == 1.60.EUR * 2.5assertEquals 4.EUR, 1.60.EUR * 2.5
assertEquals 250.EUR, (10.EUR + 15.EUR) * 10assertEquals 25.EUR, (100.EUR + 150.EUR) / 10assertEquals 2.5.EUR, (10.EUR + 15.EUR) / 10assertEquals 250.EUR, 10 * (10.EUR + 15.EUR)
In Groovy tutto è un oggetto, quindi anche gli interi ed i decimali lo sono.Fornendo una Closure di valutazione innescata dalla ricerca di una property sulle classi numeriche, ed associandola alla MetaClass dele classi numeriche possiamo intercettare la valutazione della notazione postfissa e piegarla alle nostre esigenze.
Alberto Brandolini - [email protected] – Grails-ITJavaday Roma III Edizione – 24 gennaio 2009
...proviamo a spingerci oltre...
Funziona! :-)
20
assertEquals 250.€, 10.€ * 25
assertEquals 250.$, 10.$ * 25
assertEquals 250.£, 10.£ * 25
Errore di compilazione :-(
...Pure peggio :-(
E’ abbastanza interessante notare che l’ipotetico passo successivo ci viene però sbarrato dalla struttura del linguaggio, in maniera asimmetrica rispetto ala valuta utilizzata. In particolar modo per il tradizionale ruolo del simbolo ‘$’ come operatore.
… non resta che passare alla moneta unica!
Alberto Brandolini - [email protected] – Grails-ITJavaday Roma III Edizione – 24 gennaio 2009
21
Però, così facendo, finisco per attribuire alla classe Number responsabilità che non le competono, violando uno dei principi della OOP
Stiamo definendo nuovi modi per creare istanze della classe Money, ma stiamo distribuendo il codice di pertinenza nelle gerarchie della classi numeriche che dovrebbero restare agnostiche rispetto a Money. Le classi della famiglia Number non vengono toccate direttamente, però non stiamo lavorando in modalità OOP “canonica”
Alberto Brandolini - [email protected] – Grails-ITJavaday Roma III Edizione – 24 gennaio 2009
Legacy e Black Bok
Il foglio bianco è il sogno di ogni programmatore.
La dura realtà ...è il legacy.
Vorremmo avere le stesse possibilità espressive, senza operare in modalità white-box
22
- maggiore espressività su librerie Java
- reversibilità delle operazioni
La prova effetuata su Money, è interessante, ma non è forse realistica. In un contesto reale non sempre godiamo del privilegio di poter “riscrivere tutto in groovy”, vediamo che si può fare in modalità:
Alberto Brandolini - [email protected] – Grails-ITJavaday Roma III Edizione – 24 gennaio 2009
23non vedo, non sento, non parlo.
Alberto Brandolini - [email protected] – Grails-ITJavaday Roma III Edizione – 24 gennaio 2009
Joda Time
Libreria con funzionalità avanzate per Date e TimeCandidata alla sostituzione di java.util.Date nelle
prossime versioni di JavaSupporto out-of-the box per Hibernatesupporto out-of-the box per JSP
24
Alberto Brandolini - [email protected] – Grails-ITJavaday Roma III Edizione – 24 gennaio 2009
Black Box approach
Prendendo in esame qualcosa di più complesso, ha senso rivolgersi all’esistente.
In ambito DSL alcune aree di maggior complessità risultano già coperte:
- Date ed Intervalli con Time and Money- Date ed Intervalli con Groovy (Duration, etc.)- Joda Time- JScience
25
Alberto Brandolini - [email protected] – Grails-ITJavaday Roma III Edizione – 24 gennaio 2009
Amount m3 = Amount.valueOf(3, KILO(GRAM));Amount m2 = Amount.valueOf(“2 Kg”);
JScience
Libreria con supporto per:- unità di misura (SI)- quantità- calcoli type-safe
26
Alberto Brandolini - [email protected] – Grails-ITJavaday Roma III Edizione – 24 gennaio 2009
Il punto della situazione
27Ho molti potenziali candidati a diventare DSL utili all’interno del mio contesto applicativo, in particolare per le aree dove la sintassi del inguaggo java si dimostra particolarmente infelice (le date sono un esempio lampante). Ciò spingerebbe verso una modularizzazione ed un uso estensivo dei DSL. D’altra parte l’implementazione dei DSL è semplice in termini di righe di codice, ma decisamente complicata in termini di debugging, per cui sarabbe bene che fosse il più possibile disaccoppiata dal codice applicativo.
Alberto Brandolini - [email protected] – Grails-ITJavaday Roma III Edizione – 24 gennaio 2009
Il punto della situazione
27
Molti DSL già disponibili “off the shelf” :-)
Ho molti potenziali candidati a diventare DSL utili all’interno del mio contesto applicativo, in particolare per le aree dove la sintassi del inguaggo java si dimostra particolarmente infelice (le date sono un esempio lampante). Ciò spingerebbe verso una modularizzazione ed un uso estensivo dei DSL. D’altra parte l’implementazione dei DSL è semplice in termini di righe di codice, ma decisamente complicata in termini di debugging, per cui sarabbe bene che fosse il più possibile disaccoppiata dal codice applicativo.
Alberto Brandolini - [email protected] – Grails-ITJavaday Roma III Edizione – 24 gennaio 2009
Il punto della situazione
27
Molti DSL già disponibili “off the shelf” :-)
possibilità espressive interessanti :-)
Ho molti potenziali candidati a diventare DSL utili all’interno del mio contesto applicativo, in particolare per le aree dove la sintassi del inguaggo java si dimostra particolarmente infelice (le date sono un esempio lampante). Ciò spingerebbe verso una modularizzazione ed un uso estensivo dei DSL. D’altra parte l’implementazione dei DSL è semplice in termini di righe di codice, ma decisamente complicata in termini di debugging, per cui sarabbe bene che fosse il più possibile disaccoppiata dal codice applicativo.
Alberto Brandolini - [email protected] – Grails-ITJavaday Roma III Edizione – 24 gennaio 2009
Il punto della situazione
27
Molti DSL già disponibili “off the shelf” :-)
Debugging dei DSL :-(
possibilità espressive interessanti :-)
Ho molti potenziali candidati a diventare DSL utili all’interno del mio contesto applicativo, in particolare per le aree dove la sintassi del inguaggo java si dimostra particolarmente infelice (le date sono un esempio lampante). Ciò spingerebbe verso una modularizzazione ed un uso estensivo dei DSL. D’altra parte l’implementazione dei DSL è semplice in termini di righe di codice, ma decisamente complicata in termini di debugging, per cui sarabbe bene che fosse il più possibile disaccoppiata dal codice applicativo.
Alberto Brandolini - [email protected] – Grails-ITJavaday Roma III Edizione – 24 gennaio 2009
Il punto della situazione
27
Molti DSL già disponibili “off the shelf” :-)
Debugging dei DSL :-( I DSL agiscono
sulle stesse Classi chiave :-/
possibilità espressive interessanti :-)
Ho molti potenziali candidati a diventare DSL utili all’interno del mio contesto applicativo, in particolare per le aree dove la sintassi del inguaggo java si dimostra particolarmente infelice (le date sono un esempio lampante). Ciò spingerebbe verso una modularizzazione ed un uso estensivo dei DSL. D’altra parte l’implementazione dei DSL è semplice in termini di righe di codice, ma decisamente complicata in termini di debugging, per cui sarabbe bene che fosse il più possibile disaccoppiata dal codice applicativo.
Alberto Brandolini - [email protected] – Grails-ITJavaday Roma III Edizione – 24 gennaio 2009
Il punto della situazione
27
Molti DSL già disponibili “off the shelf” :-)
Debugging dei DSL :-( I DSL agiscono
sulle stesse Classi chiave :-/
possibilità espressive interessanti :-)
Sovrapposizioni fra i differenti dialetti :-/
Ho molti potenziali candidati a diventare DSL utili all’interno del mio contesto applicativo, in particolare per le aree dove la sintassi del inguaggo java si dimostra particolarmente infelice (le date sono un esempio lampante). Ciò spingerebbe verso una modularizzazione ed un uso estensivo dei DSL. D’altra parte l’implementazione dei DSL è semplice in termini di righe di codice, ma decisamente complicata in termini di debugging, per cui sarabbe bene che fosse il più possibile disaccoppiata dal codice applicativo.
Alberto Brandolini - [email protected] – Grails-ITJavaday Roma III Edizione – 24 gennaio 2009
28Gli effetti della sovrapposizione degli interventi sulle stesse classi chiave possono infatti essere sorprendenti e presentarsi in aree applicative molto lontane da dove il problema è stato effettivamente introdotto.
Alberto Brandolini - [email protected] – Grails-ITJavaday Roma III Edizione – 24 gennaio 2009
28
Groovy è bestiale, posso scrivere i miei
DSL!!
Gli effetti della sovrapposizione degli interventi sulle stesse classi chiave possono infatti essere sorprendenti e presentarsi in aree applicative molto lontane da dove il problema è stato effettivamente introdotto.
Alberto Brandolini - [email protected] – Grails-ITJavaday Roma III Edizione – 24 gennaio 2009
28
Groovy è bestiale, posso scrivere i miei
DSL!!
Fico!
...quasi quasi me ne faccio uno
anche io...
Gli effetti della sovrapposizione degli interventi sulle stesse classi chiave possono infatti essere sorprendenti e presentarsi in aree applicative molto lontane da dove il problema è stato effettivamente introdotto.
Alberto Brandolini - [email protected] – Grails-ITJavaday Roma III Edizione – 24 gennaio 2009
28
Groovy è bestiale, posso scrivere i miei
DSL!!
Fico!
...quasi quasi me ne faccio uno
anche io...Grande!
posso riscrivere la grammatica del linguaggio!!!
Gli effetti della sovrapposizione degli interventi sulle stesse classi chiave possono infatti essere sorprendenti e presentarsi in aree applicative molto lontane da dove il problema è stato effettivamente introdotto.
Alberto Brandolini - [email protected] – Grails-ITJavaday Roma III Edizione – 24 gennaio 2009
28
Groovy è bestiale, posso scrivere i miei
DSL!!
Fico!
...quasi quasi me ne faccio uno
anche io...Grande!
posso riscrivere la grammatica del linguaggio!!!
Credono di essere capaci solo loro? Mo’ gli
faccio vedere...
Gli effetti della sovrapposizione degli interventi sulle stesse classi chiave possono infatti essere sorprendenti e presentarsi in aree applicative molto lontane da dove il problema è stato effettivamente introdotto.
Alberto Brandolini - [email protected] – Grails-ITJavaday Roma III Edizione – 24 gennaio 2009
28
Groovy è bestiale, posso scrivere i miei
DSL!!
Fico!
...quasi quasi me ne faccio uno
anche io...Grande!
posso riscrivere la grammatica del linguaggio!!!
Credono di essere capaci solo loro? Mo’ gli
faccio vedere...
Hey!
ho quest’errore strano...
Gli effetti della sovrapposizione degli interventi sulle stesse classi chiave possono infatti essere sorprendenti e presentarsi in aree applicative molto lontane da dove il problema è stato effettivamente introdotto.
Alberto Brandolini - [email protected] – Grails-ITJavaday Roma III Edizione – 24 gennaio 2009
Multiple DSL
Un unico punto di innesco configurabile per più DSL
DSL Modulari e componibili
29
- Fare convivere più DSL nello stesso contesto applicativo
- Separazione netta delle responsabilità
Vorremmo quindi la possibilità di disporre di un punto di controllo centralizzato per coordinare più DSL a granularità fine. Ovviamente supponendo che questo siano adeguatamente testati e supportati così da poterci effettivamente concentrare solo sul codice applicativo con in più le nuove potenzialità espressive.
Alberto Brandolini - [email protected] – Grails-ITJavaday Roma III Edizione – 24 gennaio 2009
DSL Descriptor
Repository di delle caratteristiche specifiche del nostro DSLparole chiaveoperatorioperazioni di setUp
30Un primo elemento di questo nuovo approccio è la definizione d un descrittore del DSL che esponga le caratteristiche specifiche del nostro DSL in formato standard.
Alberto Brandolini - [email protected] – Grails-ITJavaday Roma III Edizione – 24 gennaio 2009
Scenario Money
Corretta allocazione delle responsabilità tra la classe ed il descrittore
Riscruttura del codiceInterazione con i tipi
primitivi
getPostfixOperation
<<Interface>>
DSLDescriptor
OperationOperation
AttributeAttribute
MoneyDSLDescriptor
plus(...)minus(...)...
Currency currencyBigDecimal amount
Money
multiply(..)getReference()
Currency currencyBigDecimal amount
Number
ExpandoMetaClass
31In uno scenario come quello di money, il descrittore si limita a coordinare le operazioni sulle classi esterne al subdominio (nel nostro caso la classe Number), mentre le classi caratteristiche del DSL (Money) sono in grado di definire da sole il proprio comportamento.
Alberto Brandolini - [email protected] – Grails-ITJavaday Roma III Edizione – 24 gennaio 2009
Scenario Time and Money
Libreria complessa e già testata
Maggiore ricorso alla EMC
getPostfixOperation
<<Interface>>
DSLDescriptor
OperationOperation
AttributeAttribute
TimeAndMoneyDSLDescriptor
plus(...)minus(...)...
CalendarDate
multiply(..)getReference()
Currency currencyBigDecimal amount
Number
plus(...)minus(...)...
TimeInterval
getReferenceString
ExpandoMetaClass
32Nel caso Time & Money, il nostro descrittore contiene una logica più complessa, e funge anche da repository delle closure di valutazione delle classi del sottodominio delle date, per i metodi non direttamente esposti da queste.
Alberto Brandolini - [email protected] – Grails-ITJavaday Roma III Edizione – 24 gennaio 2009
DSLEngine
Un ruolo di coordinatore centralizzato per l’attivazione simultanea di più DSL
Si aprono nuovi problemi:- priorità nell’ordine della risoluzione- sovrapposizione degli operatori- registrazione e de-registrazione dei DSL
33Al centro di questo scenario si collocherà il nostro coordinatore.Dotato di risoluzione della priorità di valutazione, di gestione dei conflitti tra operatori utilizzati da più dialetti, e delle funzionalità di registrazione e de-registrazione dei DSL
Alberto Brandolini - [email protected] – Grails-ITJavaday Roma III Edizione – 24 gennaio 2009
Separazione delle responsabilità:
Engine come punto di coordinamento
Descriptor come componente pluggabile
OperationOperation
<<Interface>>
DSLEnginegetPostfixOperation
<<Interface>>
DSLDescriptor
OperationOperation
AttributeAttribute
MoneyDSLDescriptor
OperationOperation
priorityAbstractDSLDescriptor
OperationOperation
AttributeAttribute
QuantityDSLDescriptor
OperationOperation
AttributeAttribute
TimeDSLDescriptor
OperationOperation
AttributeAttribute
JodaTimeDSLDescriptor
34
Alberto Brandolini - [email protected] – Grails-ITJavaday Roma III Edizione – 24 gennaio 2009
DSL Multipli
...perché limitarci ad uno solo quando possiamo combinarne più di uno?
35
OperationOperation
<<Interface>>
DSLEnginegetPostfixOperation
<<Interface>>
DSLDescriptor
OperationOperation
AttributeAttribute
MoneyDSLDescriptor
OperationOperation
AttributeAttribute
QuantityDSLDescriptor
EUR, USD, GBP
k, M, ...
Perchè è interessante combinare più DSL?Perchè in determinate circostanze, l’unione di più componenti semplici può risultare significativa. in questo caso combinando Money e Quantity abbiamo una grammatica abbastanza significativa.
Alberto Brandolini - [email protected] – Grails-ITJavaday Roma III Edizione – 24 gennaio 2009
DSL Compositi
A volte, la maggiore espressività si raggiunge componendo frammenti di DSL separati
36
assert 20.k.EUR == 10.EUR * 2000
Che permette una notazione sintetica dei grandi numeri combinando due grammatiche definite indipendentemente l’una dall’altra.
Alberto Brandolini - [email protected] – Grails-ITJavaday Roma III Edizione – 24 gennaio 2009
DSL Compositi
A volte, la maggiore espressività si raggiunge componendo frammenti di DSL separati
36
assert 20.k.EUR == 10.EUR * 2000
QuantityDSL
Che permette una notazione sintetica dei grandi numeri combinando due grammatiche definite indipendentemente l’una dall’altra.
Alberto Brandolini - [email protected] – Grails-ITJavaday Roma III Edizione – 24 gennaio 2009
DSL Compositi
A volte, la maggiore espressività si raggiunge componendo frammenti di DSL separati
36
assert 20.k.EUR == 10.EUR * 2000
MoneyDSL
QuantityDSL
Che permette una notazione sintetica dei grandi numeri combinando due grammatiche definite indipendentemente l’una dall’altra.
Alberto Brandolini - [email protected] – Grails-ITJavaday Roma III Edizione – 24 gennaio 2009
Grails
Framework per lo sviluppo rapido di applicazioni Web (ma non solo)
- basato su Groovy- si appoggia su librerie Java note e provate
(Spring, Hibernate, Quartz, etc.)- integrabile con svariate tecnologie
- La risposta a Ruby on Rails sulla JVM- migliore curva di apprendimento dal mondo Java- infrastruttura spesso già installata
37
Alberto Brandolini - [email protected] – Grails-ITJavaday Roma III Edizione – 24 gennaio 2009
Grails
38In 2 parole: Grails permette di partire da una definizione estremamente sintetica delle classi di dominio, per generare lo strato di presentation (con navigazione e validazione del dato sulla base dei constraints definiti dall’utente) e tutto il codice di gestione della persistenza (comprese del DDL di popolamento del database) che permettono la realizzazione di una CRUD application in tempi brevissimi
Alberto Brandolini - [email protected] – Grails-ITJavaday Roma III Edizione – 24 gennaio 2009
Grails
38
create-
domain-class
In 2 parole: Grails permette di partire da una definizione estremamente sintetica delle classi di dominio, per generare lo strato di presentation (con navigazione e validazione del dato sulla base dei constraints definiti dall’utente) e tutto il codice di gestione della persistenza (comprese del DDL di popolamento del database) che permettono la realizzazione di una CRUD application in tempi brevissimi
Alberto Brandolini - [email protected] – Grails-ITJavaday Roma III Edizione – 24 gennaio 2009
Grails
38
create-
domain-class
class Persona { String nome String cognome String e-mail Date dataNascita …}
In 2 parole: Grails permette di partire da una definizione estremamente sintetica delle classi di dominio, per generare lo strato di presentation (con navigazione e validazione del dato sulla base dei constraints definiti dall’utente) e tutto il codice di gestione della persistenza (comprese del DDL di popolamento del database) che permettono la realizzazione di una CRUD application in tempi brevissimi
Alberto Brandolini - [email protected] – Grails-ITJavaday Roma III Edizione – 24 gennaio 2009
Grails
38
create-controller
create-
domain-class
class Persona { String nome String cognome String e-mail Date dataNascita …}
In 2 parole: Grails permette di partire da una definizione estremamente sintetica delle classi di dominio, per generare lo strato di presentation (con navigazione e validazione del dato sulla base dei constraints definiti dall’utente) e tutto il codice di gestione della persistenza (comprese del DDL di popolamento del database) che permettono la realizzazione di una CRUD application in tempi brevissimi
Alberto Brandolini - [email protected] – Grails-ITJavaday Roma III Edizione – 24 gennaio 2009
Grails
38
create-controller
create-
domain-class
class PersonaController { def list = { … } def create = { … } …}
class Persona { String nome String cognome String e-mail Date dataNascita …}
In 2 parole: Grails permette di partire da una definizione estremamente sintetica delle classi di dominio, per generare lo strato di presentation (con navigazione e validazione del dato sulla base dei constraints definiti dall’utente) e tutto il codice di gestione della persistenza (comprese del DDL di popolamento del database) che permettono la realizzazione di una CRUD application in tempi brevissimi
Alberto Brandolini - [email protected] – Grails-ITJavaday Roma III Edizione – 24 gennaio 2009
Grails
38
create-controller
create-
domain-class
Id dataNascitaeMailcognomenome
Persone
class PersonaController { def list = { … } def create = { … } …}
class Persona { String nome String cognome String e-mail Date dataNascita …}
In 2 parole: Grails permette di partire da una definizione estremamente sintetica delle classi di dominio, per generare lo strato di presentation (con navigazione e validazione del dato sulla base dei constraints definiti dall’utente) e tutto il codice di gestione della persistenza (comprese del DDL di popolamento del database) che permettono la realizzazione di una CRUD application in tempi brevissimi
Alberto Brandolini - [email protected] – Grails-ITJavaday Roma III Edizione – 24 gennaio 2009
Grails
38
create-controller
create-
domain-class
Id dataNascitaeMailcognomenome
Persone
create-v
iew
class PersonaController { def list = { … } def create = { … } …}
class Persona { String nome String cognome String e-mail Date dataNascita …}
In 2 parole: Grails permette di partire da una definizione estremamente sintetica delle classi di dominio, per generare lo strato di presentation (con navigazione e validazione del dato sulla base dei constraints definiti dall’utente) e tutto il codice di gestione della persistenza (comprese del DDL di popolamento del database) che permettono la realizzazione di una CRUD application in tempi brevissimi
Alberto Brandolini - [email protected] – Grails-ITJavaday Roma III Edizione – 24 gennaio 2009
Grails
38
create-controller
create-
domain-class
Id dataNascitaeMailcognomenome
Persone
create-v
iew
class PersonaController { def list = { … } def create = { … } …}
class Persona { String nome String cognome String e-mail Date dataNascita …}
In 2 parole: Grails permette di partire da una definizione estremamente sintetica delle classi di dominio, per generare lo strato di presentation (con navigazione e validazione del dato sulla base dei constraints definiti dall’utente) e tutto il codice di gestione della persistenza (comprese del DDL di popolamento del database) che permettono la realizzazione di una CRUD application in tempi brevissimi
Alberto Brandolini - [email protected] – Grails-ITJavaday Roma III Edizione – 24 gennaio 2009
Grails
38
create-controller
create-
domain-class
Id dataNascitaeMailcognomenome
Persone
create-v
iew
class PersonaController { def list = { … } def create = { … } …}
class Persona { String nome String cognome String e-mail Date dataNascita …}
Entity
In 2 parole: Grails permette di partire da una definizione estremamente sintetica delle classi di dominio, per generare lo strato di presentation (con navigazione e validazione del dato sulla base dei constraints definiti dall’utente) e tutto il codice di gestione della persistenza (comprese del DDL di popolamento del database) che permettono la realizzazione di una CRUD application in tempi brevissimi
Alberto Brandolini - [email protected] – Grails-ITJavaday Roma III Edizione – 24 gennaio 2009
Grails
38
create-controller
create-
domain-class
Id dataNascitaeMailcognomenome
Persone
create-v
iew
class PersonaController { def list = { … } def create = { … } …}
class Persona { String nome String cognome String e-mail Date dataNascita …}
Entity
Value Objectclass Money { Currency currency BigDecimal amount
…}
In 2 parole: Grails permette di partire da una definizione estremamente sintetica delle classi di dominio, per generare lo strato di presentation (con navigazione e validazione del dato sulla base dei constraints definiti dall’utente) e tutto il codice di gestione della persistenza (comprese del DDL di popolamento del database) che permettono la realizzazione di una CRUD application in tempi brevissimi
Alberto Brandolini - [email protected] – Grails-ITJavaday Roma III Edizione – 24 gennaio 2009
Grails
38
create-controller
create-
domain-class
Id dataNascitaeMailcognomenome
Persone
create-v
iew
class PersonaController { def list = { … } def create = { … } …}
class Persona { String nome String cognome String e-mail Date dataNascita …}
Entity
Value Objectclass Money { Currency currency BigDecimal amount
…}
?
In 2 parole: Grails permette di partire da una definizione estremamente sintetica delle classi di dominio, per generare lo strato di presentation (con navigazione e validazione del dato sulla base dei constraints definiti dall’utente) e tutto il codice di gestione della persistenza (comprese del DDL di popolamento del database) che permettono la realizzazione di una CRUD application in tempi brevissimi
Alberto Brandolini - [email protected] – Grails-ITJavaday Roma III Edizione – 24 gennaio 2009
Grails
38
create-controller
create-
domain-class
Id dataNascitaeMailcognomenome
Persone
create-v
iew
class PersonaController { def list = { … } def create = { … } …}
class Persona { String nome String cognome String e-mail Date dataNascita …}
Entity
Value Objectclass Money { Currency currency BigDecimal amount
…}
? ?In 2 parole: Grails permette di partire da una definizione estremamente sintetica delle classi di dominio, per generare lo strato di presentation (con navigazione e validazione del dato sulla base dei constraints definiti dall’utente) e tutto il codice di gestione della persistenza (comprese del DDL di popolamento del database) che permettono la realizzazione di una CRUD application in tempi brevissimi
Alberto Brandolini - [email protected] – Grails-ITJavaday Roma III Edizione – 24 gennaio 2009
Value Object in Grails
Grails nasce privo del concetto di Value Object:- il dominio applicativo nasce in corrispondenza 1-1
con il database sottostante- localizzazione della logica applicativa nelle classi
di dominio- La gestione di eventuali tipi di dato ricorrenti è
delegata a Hibernate via Gorm
39
Alberto Brandolini - [email protected] – Grails-ITJavaday Roma III Edizione – 24 gennaio 2009
Ed il nostro DSL?
Il supporto ai tipi di dato definiti dall’utente passa attraverso:- Grails Scaffolding
- che però riconosce e gestisce di default solo i tipi primitivi
- GORM- che delega la gestione agli User Type di Hibernate
40
Grails Scaffolding
Così com’è Grails non ci permette di trarre il meglio dal DSL e dai tipi di dato che lo caratterizzano. La generazione delle pagine e dello strato di persistenza non ha infatti le informazioni necessarie per generare pagine e database così come avviene per le classi di dominio basate sui dati primitivi.
Alberto Brandolini - [email protected] – Grails-ITJavaday Roma III Edizione – 24 gennaio 2009
Obiettivi
Componente di presentation che mirato sulle caratteristiche specifiche del nostro oggetto
Grails deve essere in grado di riconoscere le istanze del nostro oggetto ed integrarle nel proprio processo di creazione della view
- Widget riutilizzabile
- integrato nel processo di scaffolding
42Il nostro obiettivo è ora quello di verificare i punti di espansione e customizzazione offerti dalla piattaforma per allargare le potenzialità di Grails anche al nostro DSL.
Alberto Brandolini - [email protected] – Grails-ITJavaday Roma III Edizione – 24 gennaio 2009
Tag Libraries in Java
La scrittura di una tag library in Java è un’operazione abbastanza punitiva
- sintassi ed API di basso livello- integrazione conl’ambiente di sviluppo non eccelsa- processo di registrazione delle taglibraries- … varie ed eventuali
43
Alberto Brandolini - [email protected] – Grails-ITJavaday Roma III Edizione – 24 gennaio 2009
44Fortunatamente abbiamo scoperto chi è l’autore delle specifiche :-)
Alberto Brandolini - [email protected] – Grails-ITJavaday Roma III Edizione – 24 gennaio 2009
Tag Libraries
>grails create-taglib
‐ grailscreailsorgentedellanostraTagLibrarynellacartellataglib
‐ contestualmentecreaancheilcorrispondentetestnellacartella/test/integration
45In grails la gestione delle tag libraries è largamente semplificata:- si tratta di un’operazione gestita diretamente dal framework, che provvede anche a creare i test.
Alberto Brandolini - [email protected] – Grails-ITJavaday Roma III Edizione – 24 gennaio 2009
Tag Libraries in Grails
-Illusione di un unico spazio condiviso:-possibile referenziare altri tags
direttamente all’interno del nostro codice-sintassi estremamente semplice-tag già registrati
def money = { attrs -> ...
out << currencySelect(name:"${attrs.name}.currency", value:attrs.value.currency) out << textField(name:"${attrs.name}.amount", value:attrs.value.amount)}
46Inoltre la gestione dei namespaces è opzionale: di default il namespace è condiviso con le tag di sistema, permettendo di referenziarle direttamente da codice.
Alberto Brandolini - [email protected] – Grails-ITJavaday Roma III Edizione – 24 gennaio 2009
Extending Grails Scaffolding
RenderEditor.templatecontiene le direttive di Grails per lo Scaffolding
...
...DefaultGrailsTemplateGenerator
setResourceLoader(ResourceLoader)generateViews(GrailsDomainClass, String)generateController(GrailsDomainClass, String)setOverwrite(boolean)generateView(GrailsDomainClass, String, Writer)generateController(GrailsDomainClass, Writer)
<<Interface>>
GrailsTemplateGenerator
!"#$"%&$'()%*("+,-.("
47Una volta definito il nostro componente grafico per il rendering, il nostro obiettivo è quello di renderlo parte del processo di scaffolding di Grails. é sufficiente andare a modificare il template offerto da Grails.
Alberto Brandolini - [email protected] – Grails-ITJavaday Roma III Edizione – 24 gennaio 2009
GORM
48
Tipi persistenti riutilizzabili
Integrati nel processo di scaffolding
Per quanto riguarda la gestione della persistenza gestita da GORM, di fatto stiamo interagendo quasi direttamente con Hibernate.
Alberto Brandolini - [email protected] – Grails-ITJavaday Roma III Edizione – 24 gennaio 2009
Scrittura degli User Type semplificata dalle caratteristiche dei Value Object
Discriminazione delle strategie di persistenza sulla base della classe
49
class BankingAccount { String name String bank String iban Money currentBalance Currency currency
static hasMany = [operations:BankingOperation, statements:Statement]
static embedded = ['currentBalance']
static mapping = { columns { currentBalance type:MoneyCurrencyUserType } }
Sarà necessario disporre di Hibernate User Type corrispondenti ai tipi di dato caratteristici del nostro DSL. Si tratta di un’operazione inizialmente tediosa che può essere notevolmente semplificata ricordando che si tratta generalmente di Value Object con la caratteristica dell’immutabilità.
Alberto Brandolini - [email protected] – Grails-ITJavaday Roma III Edizione – 24 gennaio 2009
...considerazioni finali
Non reinventare la ruota:Alcuni dialetti già disponibili off-the shelfI linguaggi interessanti esistono già, non dobbiamo
inventarliL’utente ha (quasi) sempre ragioneKeep it Simple Stupid:
Non aggiungiamo nulla che non servaTest, Test ed ancora Test:
… e magari se rimane tempo, qualche altro test
50Groovy offre una soluzione di compromesso interessante sul panorama dei DSL e Grails ne permette l’integrazione in maniera tutto sommato agevole.
Alberto Brandolini - [email protected] – Grails-ITJavaday Roma III Edizione – 24 gennaio 2009
Domande?
51
Alberto Brandolini - [email protected] – Grails-ITJavaday Roma III Edizione – 24 gennaio 2009
Riferimenti
52
Alberto Brandolini - [email protected] – Grails-ITJavaday Roma III Edizione – 24 gennaio 2009
Riferimenti
http://groovy.codehaus.org/
http://grails.org
53
Alberto Brandolini - [email protected] – Grails-ITJavaday Roma III Edizione – 24 gennaio 2009
Riferimenti
JScience: http://jscience.org/ Joda Time: http://www.joda.org/ Time and Money: http://
timeandmoney.sourceforge.net/ http://glaforge.free.fr/weblog/http://www.warneronstine.com/blog/articles/
2008/04/24/groovy-dsl-roundup http://peterbacklund.blogspot.com/ http://www.jakusys.de
54
Alberto Brandolini - [email protected] – Grails-ITJavaday Roma III Edizione – 24 gennaio 2009
Riferimenti
Grails-IT: http://it.groups.yahoo.com/group/Grails-IT/Mokabyte: http://www.mokabyte.it
http://ziobrando.blogspot.comhttp://albertobrandolini.wikidot.com
55
Alberto Brandolini - [email protected] – Grails-ITJavaday Roma III Edizione – 24 gennaio 2009
Open Source it!
Sorgenti presto su:http://code.google.com/p/diesel/
56