Perché gli sviluppatori Java dovrebbero dare una possibilità a Grail?

Pubblicato: 2022-03-11

Java ha un ecosistema che è maturato in anni di sviluppo, affermandosi come una delle piattaforme più affidabili in circolazione. Eppure manca dei mezzi necessari per portare a termine il lavoro rapidamente, soprattutto per cose come le applicazioni web. Nel tentativo di evitare frustrazioni con questo tipo di problemi, gli sviluppatori spesso optano invece per linguaggi di implementazione e per i loro moderni framework web, come Ruby con Ruby on Rails, Python con Django e così via. A differenza di Java, questi forniscono un percorso molto più snello per la creazione di un'applicazione web.

Perché gli sviluppatori Java dovrebbero dare una possibilità a Grail?

Sviluppatori web Java: incontra Grails e scopri cosa ti sei perso.
Twitta

Fortunatamente, per gli sviluppatori Java che vogliono creare applicazioni web, c'è un modo migliore e coinvolge Grails. In questo articolo, vedremo come Grails with Groovy sia una valida alternativa nel regno JVM. Vedremo alcuni esempi in cui Grails si rivolge a noi come sviluppatori Java e potrebbe tentare anche qualcun altro di provare.

La storia

In una startup per cui ho lavorato, abbiamo avuto questo problema esatto. Avevamo un'applicazione Spring che stava diventando una seccatura con cui lavorare. Con l'aumento delle dimensioni, abbiamo presto scoperto che il refactoring e l'aggiunta di funzionalità ci richiedevano molto più tempo del dovuto. La combinazione di questo con alcune altre motivazioni ci ha portato a decidere di riscrivere la nostra applicazione principale. Eravamo anche aperti a cambiare o sostituire lo stack tecnologico esistente. Grails sembrava una scelta praticabile poiché funziona nella JVM ed è basato su tecnologie che già conoscevamo. Utilizza il linguaggio di programmazione Groovy ma allo stesso tempo permette di mescolarlo con Java. Quindi abbiamo fatto il grande passo.

Avanti tutta

Una cosa in cui Grails eccelle davvero è semplificare l'avvio di un nuovo progetto. È semplice come eseguire un comando che crea la struttura del progetto con tutte le cartelle necessarie per le classi che aggiungerai in seguito. L'aggiunta di classi modello, controller, servizi e pagine Web richiede uno sforzo altrettanto minimo. L'unica cosa di cui devi occuparti è nominare e posizionare correttamente le cose. A differenza di Java, non esiste praticamente alcun codice standard che debba essere presente solo perché deve esserci. Ciò è in parte reso possibile dall'utilizzo di Spring e Hibernate che sono due dei pilastri del Grail, così come dal concetto di codifica per convenzione. Per eseguire il progetto, Grails viene fornito in bundle con Apache Tomcat come server di sviluppo. Tutto quello che dobbiamo fare è eseguire il progetto nel nostro IDE e il server verrà avviato con il nostro codice distribuito. Inoltre, la mappatura relazionale degli oggetti (GORM) di Grails con Hibernate si occuperà della creazione del database per noi. Per utilizzare un database esistente, è necessario configurare le proprietà di connessione JDBC o semplicemente lasciarlo per impostazione predefinita per utilizzare un'istanza in memoria. Una volta che il server con Grails è in esecuzione (richiede un po' più di un'applicazione Spring MVC), possiamo modificare il codice e la funzionalità di distribuzione a caldo manterrà la nostra sessione di debug equipaggiata con l'ultima versione. Le uniche classi che non possono essere ricaricate in questo modo sono le classi di entità.

La compilazione del database può essere eseguita utilizzando gli script SQL, ma può diventare noioso. Tutti i progetti Grails contengono una classe Bootstrap che verrà eseguita quando viene eseguita la nostra applicazione. In questa classe, possiamo archiviare o modificare i dati e quindi inizializzare lo stato dell'applicazione. Questo si è rivelato molto utile per noi, quindi abbiamo subito alcuni casi di test nella versione di sviluppo.

Nella classe Bootstrap, possiamo anche utilizzare le condizioni "if" per verificare il tipo di ambiente (sviluppo, test, produzione, ecc.) e modificare i dati di conseguenza.

Manipolazione dei dati

Una delle cose che ha immediatamente attirato la nostra attenzione con Grails è stata la facilità di lavorare con i dati. La lettura dal database è un'attività che deve essere ripetuta più e più volte. E molte volte è semplice. Come recuperare una o più entità che soddisfano determinati criteri e quindi aggregarle. Perché non utilizzare un cercatore dinamico per questo? È un modo per eseguire query sui dati in cui i metodi vengono creati dinamicamente in fase di esecuzione. Tutto quello che devi fare è seguire una convenzione di denominazione.

 def users = User.findAllByLastNameLikeOrAgeGreaterThan('Doe%', 30)

La riga sopra la riga recupererà tutti gli oggetti utente con cognome che inizia con "Doe" o età maggiore di 30. Sì, non è un caso molto sofisticato ma ottieni l'essenza.

E se volessimo filtrare ulteriormente questo elenco per quelli che hanno la proprietà "failedLogins" maggiore di 10? E se volessimo ordinarli in base alla data di creazione? E se volessimo concatenare i loro nomi o trovare l'età massima degli utenti restituiti?

 users = users.findAll() { it.failedLogins > 10 } users = users.sort { it.dateCreated } def firstNamesString = users.firstName.join(', ') def maximumAge = users.age.max()

Gli esempi precedenti possono sembrare semplici, ma mostrano quanto possa essere potente Grail per interrogare, filtrare e manipolare i dati. In Java 8, puoi ottenere risultati simili per alcuni di questi casi, ma richiederà comunque più codice di Grails.

A volte voglio creare in modo diverso

Un costruttore dinamico o un costruttore di argomenti denominati è una funzionalità che molti di noi volevano avere in Java. È bello definire quali costruttori consente una determinata classe, ma in molti casi vuoi solo impostare alcune proprietà e ottenere l'istanza maledetta. Groovy aggiunge un costruttore speciale per ogni entità che fondamentalmente prende l'eleganza di una mappa come input e imposta le proprietà con le voci della mappa.

 def Person = new Person(name: 'Batman', age: 57)

Questo approccio porta a un codice molto più espressivo ed evita la necessità di tutto il codice standard del costruttore.

E a proposito, ecco alcuni esempi della bellezza e dell'eleganza delle mappe di Groovy:

 def emptyMap = [:] def map = [bread:3, milk:5, butter:2] map['bread'] = 4 map.milk = 6

Questo è un altro esempio di come il codice può essere breve e semplice, ma potente. Mostra come utilizzare l'inizializzazione inline e come manipolare i valori della mappa in modo simile alle proprietà degli oggetti. Non c'è bisogno di chiamare i metodi Java tradizionali per la manipolazione di base, a meno che tu non lo voglia davvero.

Abbiamo bisogno di più potenza!

Naturalmente, non esiste un framework in grado di fare tutto, ma quando stiamo colmando le lacune, dovremmo vedere cos'altro potrebbe essere già disponibile prima di provare a implementare la nostra soluzione. Per espandere il nostro arsenale di funzionalità basate su Grails, possiamo utilizzare i plugin di Grails. L'installazione di un plugin viene eseguita semplicemente aggiungendo un'altra riga nella classe BuildConfig che è presente in ogni progetto Grails (la convenzione del codice colpisce ancora!).

 compile ':spring-security-core:2.0-RC4'

La riga sopra aggiunge il core di sicurezza Spring alla nostra applicazione e non c'è praticamente più alcuna configurazione necessaria per incorporare questa funzionalità.

È simile all'utilizzo delle dipendenze Maven (a cui puoi fare riferimento anche nella stessa classe di configurazione), ma i plug-in sono generalmente blocchi più grandi che contengono l'intera funzionalità.

Detto questo, lascia che ti parli di un caso che abbiamo dovuto affrontare. Avevamo bisogno di implementare una ricerca che si estendesse su diverse entità di dati. Grails ha un plugin Elasticsearch che è un gioco da ragazzi da usare. Come accennato in precedenza, dobbiamo solo fare riferimento al plug-in nel file di configurazione e siamo a posto. Se vogliamo cercare entità di una certa classe, dobbiamo solo aggiungere una proprietà statica "ricercabile" a quella classe. E se vogliamo, possiamo anche limitare le proprietà che potranno essere ricercate.

 class User { static searchable = { only = name } String name Double salary }

È così poco codice, ma sotto il cofano, Grails e il plug-in Elasticsearch indicizzeranno automaticamente tutti gli utenti per nome e ci consentiranno di cercare per nome. Anche la chiamata di ricerca vera e propria è molto concisa:

 User.search("${params.query}")

Se non vogliamo, non dovremo mai toccare l'indice Lucene. Tutto sarà fatto automaticamente per noi. Il plug-in ha anche un'API per la visualizzazione dei risultati di ricerca: può evidenziare la corrispondenza trovata all'interno del testo cercato. Questo è solo un esempio di come un plug-in può fornire un enorme pacchetto di funzionalità che possono renderci molto più efficienti evitando la necessità di implementarlo noi stessi.

Abbiamo ancora bisogno di più potenza

I plugin sono fantastici, ma a volte non abbiamo bisogno di un intero plugin, vogliamo solo qualcosa in più. Ricordi l'ultima volta che volevi avere un metodo aggiuntivo su una classe Java esistente ma non volevi (o non potevi) estenderli/sostituirli? In Groovy, puoi aggiungere metodi e proprietà a classi esistenti o anche solo a determinate istanze di esse. Ad esempio, puoi aggiungere un metodo di formatting alla classe java.util.Date che è fantastico quando vuoi formattare le date in modo coerente e semplicemente non vuoi scrivere classi di utilità statiche o definire vari filtri.

 Date.metaClass.formatDate = { delegate.format("dd.MM.yyyy") }

E se volessi ordinare un elenco di utenti in base a un valore calcolato e ne avessi bisogno solo in un caso (ad es. aggiungere un nuovo metodo nella classe User sarebbe inquinante)? Puoi aggiungere una proprietà su ciascuna di queste istanze e quindi semplicemente ordinare o filtrare la raccolta in base a quella proprietà:

 user.metaClass.computedProp = 312 * 32 * 3

Gli autori di Groovy hanno già aggiunto molti miglioramenti ad alcune delle classi principali di Java, quindi non è necessario. Di seguito sono riportati alcuni esempi.

Usando "meno" per rimuovere tutti gli elementi da una raccolta che sono presenti in un'altra raccolta.

 assert [1, 2, 3, 4, 4, 5] - [2, 4] == [1, 3, 5]

Metodi aggiuntivi per manipolare oggetti java.util.Date che tornano utili così tante volte, come aggiungere/sottrarre giorni dalle date o ottenere/impostare un determinato campo della data senza convertirlo in Calendar o utilizzare librerie aggiuntive.

 def yesterdayAllMyTroublesSeemedSoFarAway = new Date() - 1 def myAwesomeAnniversaryYear = myAwesomeDate[Calendar.YEAR] + 1 myAwesomeDate.set(year: myAwesomeAnniversaryYear, second: 0)

Quando vuoi davvero essere descrittivo con la manipolazione della data, puoi semplicemente usare la classe TimeCategory aggiunta da Groovy:

 use (TimeCategory) { println 1.minute.from.now println 10.hours.ago def someDate = new Date() println someDate - 3.months }

Un martello e un chiodo

Poi ci sono gli IDE. GGTS e IntelliJ IDEA basati su Eclipse sono impostati per lavorare con Grails. Comprendono la struttura del progetto (e ti aiuteranno a navigare tra cartelle e risorse) e hanno scorciatoie per i comandi che utilizzerai più spesso (ad esempio, aggiungi controller, aggiungi una pagina, esegui un progetto, ecc.). Con Grails eseguirai comandi (per eseguire un progetto o impostare una nuova funzionalità di plugin) e avrai bisogno di diverse configurazioni, che sono anche coperte dagli IDE. Il completamento del codice funziona bene nelle pagine dei modelli web di Grails in cui farai spesso riferimento a controller e azioni. Ci sono anche altri IDE che possono essere utilizzati con Grails come Netbeans, TextMate, Emacs e altri.

E il lato oscuro?

Proprio come con ogni cosa nella vita, anche con Grails ci sono delle avvertenze. C'è molta magia che viene fatta sotto il cofano che spesso può essere una buona cosa, ma a volte il risultato non sarà quello che ti aspettavi. I bug si verificheranno solo perché non si usa la digitazione (sì, i tipi sono facoltativi in ​​Groovy) e non si è abbastanza attenti. E forse non noterai un errore finché non sarà troppo tardi. Inoltre, è molto allettante scrivere battute per impressionare i tuoi colleghi. E tu. Ma queste potenti righe di codice potrebbero non essere così autoesplicative per i tuoi colleghi. O anche a te stesso tra un paio di mesi. Ecco perché penso che Grails richieda più disciplina di programmazione rispetto ad alcuni dei framework più tradizionali.

Il tempo è denaro

La codifica non dovrebbe richiedere più tempo solo perché il tuo attuale framework lo richiede. Soprattutto con il numero sempre più grande di startup in questi giorni, è importante concentrarsi sui compiti che contano davvero ed essere il più efficienti possibile. Il tempo è davvero denaro e il time to market è fondamentale. Devi essere in grado di agire rapidamente e implementare la soluzione prima che scada il tempo e la concorrenza ti batte.

I miei amici che lavorano con Ruby on Rails o Python/Django mi dicono da tempo quanto siano fantastiche queste tecnologie. Ed è stato davvero sciocco pensare a quanto tempo mi ci è voluto in Java per scrivere codice che memorizza qualcosa nel database e lo visualizza in una pagina web. Grail può davvero essere una risposta utile. Non è che non potresti farlo con Java puro, Spring MVC e Hibernate. Potresti. La tua applicazione potrebbe anche funzionare un po' più velocemente. Ma farai il lavoro più velocemente con Grails.

Correlati: perché è necessario eseguire già l'aggiornamento a Java 8