1. How to be an in...Fluent Developer
Breve salto del mondo delle Fluent Interface : tra pragmatismo, codice e qualche
suggerimento!
2. 2
Salve a Tutti
Stefano Fago
Tecnico Informatico per UBI Banca
https://github.com/stefanofago73
https://www.slideshare.net/stefanofago
https://www.linkedin.com/in/stefanofago/
WARNING:
Quanto vedremo non è esaustivo ma...vi verrà l'appetito!
3. 3
Fluent Interface
Il trend nasce nel 2005 ad opera di Martin Fowler e Eric Evans e si
sviluppa fino al 2013 per consolidarsi nella maggior parte dei
framework oggi in circolazione che ofrono Fluent API.
4. 4
...di cosa parliamo: un esempio?
AssertJ : Fluent Assertion for Java
assertThat(fellowshipOfTheRing)
.extracting("name", "age", "race.name")
.contains(tuple("Boromir", 37, "Man"),
tuple("Sam", 38, "Hobbit"),
tuple("Legolas", 1000, "Elf"));
5. 5
Fluent Interface
L'obiettivo è ofrire un metodo per costruire Object-Oriented API
molto leggibili (prosa) assimilabili a dei Linguaggi Domain
Specific (DSL)
6. 6
Domain Specific Language
Un Domain Specific Language è un linguaggio specializzato per
un dato dominio.
I DSL sono definiti Interni ed Esterni:
●
I DSL Esterni richiedono la definizione di un linguaggio grazie
alla teoria degli interpreti e la gestione sintassi e grammatiche.
●
I DSL Interni nascono come studio su Fluent Interface e sono
costruiti su un linguaggio ospitante.
7. 7
...ma come si costruisce un DSL Interno?
E’ possibile definire un DSL Interno in diferenti modi di cui i
principali sono:
●
Una Fluent Interface in un Linguaggio Ospite
●
Un approccio generativo utilizzando Template Engine
●
Usare un linguaggio di Scripting ospitato in un altro linguaggio
...andremo ad esplorare solo la prima opzione!
8. 8
...dal Builder Pattern a...
...Si è partiti dal concetto di Builder Design Pattern per arrivare
al Fluent Builder e poi alle Fluent API e DSL…
...che generalizzando ci portano a… Il mistero verrà risolto alla
fine delle slide!...
9. 9
Come approcciamo?
Il presupposto è portare lo sviluppo su sequenze di contesti dove
i contesti sono oggetti. Ne deriva una catena di istruzioni che
sembra una prosa.
Object A
Object B
Object A
Object C
10. 10
Strumenti di base
Gli elementi di base per costruire una Fluent Interface e, di
conseguenza, una Fluent API sono:
●
Method Chaining
●
Static Method & Static Import
●
Nested Function
●
Costrutti specifici del Linguaggio ospitante
WARNING: esempi in Java
11. 11
Method Chaining
Dato un oggetto, faccio in modo che i suoi metodi restituiscano un
riferimento all'oggetto stesso o ad altri tipi che seguiranno lo stesso stile
12. 12
Method Chaining : alcune regole
a) Ritornare this implica rimanere nello stesso contesto. Viene
usato per azioni opzionali o che possano essere invocate molteplici
volte e/o dove l'ordine non è importante.
b) Ritornare un altro oggetto vuol dire cambiare contesto. Viene
usato per raforzare il type-checking e definire un limite sulle scelte
che lo sviluppatore può fare
c) Bloccare il concatenamento viene eseguito dal non ritornare un
oggetto o ritornare un oggetto terminale che è un elemento valore.
13. 13
Elementi Statici : no more new…
In Java è possibile utilizzare gli import statici per utilizzare, senza il nome della
classe, metodi statici che possono essere usati come produttori di oggetti.
14. 14
Elementi Statici : nested elements
La stessa tecnica mi permette di concepire quanto metodi di utilità che nuovi
oggetti da annidare
15. 15
Elementi Statici : Costanti di Dominio
In Java, tra gli statics, vi sono anche le Enumerazioni che sono il concetto
type-safe di Costante.
16. 16
Definire un Elemento Terminale
Devo comprendere una modalità di chiusura del DSL con un elemento
terminale
17. 17
Method Chaining : il Cambio di Contesto
Il cambio di contesto implica mantenere un riferimento al contesto
precedente nel caso di back-to. Dal punto di vista realizzativo implica la
separazione tra interfaccia, che verrà usata come tipo di ritorno, ed
implementazione che preserverà il rapporto con il contesto parent.
18. 18
Generics : Polimorfismo & Type-Safety
E' possibile rendere un metodo generico in modo da nascondere famiglie di
oggetti pur forzando la type-safety. I Generics permettono una tipologia di
polimorfismo utile per rendere estendibili alcuni oggetti-contesto del DSL.
19. 19
Host Object : Contesti impliciti
A volte si preferisce definire un oggetto ospitante i principali concetti di
dominio ed eventuali utilità invece che ricorrere agli statics: è possibile,
quindi, avere quanto metodi d'istanza che giocare sull'ereditarietà
20. 20
Qual è il valore aggiunto?
Con una Fluent API o Internal DSL riusciamo a:
●
separare l'azione configurativa da quella esecutiva
●
guidare lo sviluppatore nella sua attività di codifica
●
guidare lo sviluppatore nell'uso delle caratteristiche avanzate
del linguaggio (Lambda? Closure? Extension methods? etc etc...)
●
diminuire side-efect, variabili temporanee e contestualizzare
sempre il processamento
●
autocompletamento/suggerimenti in IDE
21. 21
...ma ecco i problemi!
●
E' necessario un'attività di analisi del dominio target ed usare
termini ed elementi conosciuti da tutta la platea a cui ci si rivolge
●
E' necessario un'attività di progettazione dei termini e sequenze
●
E' meglio lavorare in TDD per avere un modello esecutivo del DSL
e scoprire velocemente sequenze non considerate inizialmente
●
E' dificile estendere il DSL risultante e le manutenzioni possono
essere non retro compatibili
●
Si complica il debugging e la gestione degli errori
●
Non vi è compatibilità con la specifica dei Java Beans
22. 22
Adottare un Internal DSL è allora possibile?
SI, ma...
●
E’ preferibile avere un team core che propaghi l'uso e le
evoluzioni del DSL
●
Serve una documentazione ricca di esempi e suggerimenti e
correlazione ai concetti di dominio
●
E’ necessaria l'apertura a ricevere suggerimenti, spiegare i
limiti e gli obiettivi/scope del DSL
●
Dev’esserci la disponibilità a buttare un DSL quando non è utile
●
Dev’esserci la furbizia a limitare un DSL a domini stabili e ben
definiti o con un numero limitato di concetti
23. 23
...ed il Mistero?
Cosa accadrebbe se volessi rendere ancora più generico
l'approccio alle Fluent Interface/Internal DSL?
Probabilmente… del Functional Programming (?!?!?!?!?)