Jedan od trenutnih trendova u programiranju su svakako dinamički jezici i miks funkcionalne i objektno orijentisane filozofije.Gde god se okrenete priča se o tome – pre svega tu je Ruby, iz Mikrosoftovog tabora tu je LINQ, a već uveliko pričaju o C# 4.0 koji donosi osobine dinamičnog programiranja. Java svet svakako nije ostao po strani od ovog trenda – na virtuelnoj mašini imamo JRuby, ali tu je po mom mišljenju i mnogo bolja opcija – Groovy.
Kad god spomenem drugim programerima da programiram u Groovyju, kao reakciju dobijem zbunjene poglede i češkanje po glavi. Ljudi ili nisu čuli za jezik, ili su celu priču unapred odbacili kao bespotrebnu ili neupotrebljivu u realnom svetu. S obzirom da Groovy koristim na poslu već skoro dve godine i mislim da je veoma koristan i zabavan za programiranje, pišem ovaj tekst s namerom da ga približim ljudima koji nikad nisu programirali u njemu. Ako već poznajete Javu a želite da držite korak sa najnovijim trendovima u programiranju, Groovy je za vas jednostavno idealna stvar.
Najkraće rečeno, Groovy je programski jezik. Malo duže rečeno to je dinamički objektno orijentisani programski jezik za Java virtuelnu mašinu. Za početak pogledajmo konkretan primer hello world programa u Groovyju i Javi:
Java verzija HelloWorld
1 public class HelloWorld {
|
Groovy verzija HelloWorld
1 public class HelloWorld {
|
Varate se ako ste pomislili da sam napravio copy/paste grešku i dva puta stavio isti kod. Ovo demonstrira po meni jednu od najvažnijih osobina groovy jezika – Java kod je potpuno kompatibilan sa Groovyjem.
Dakle, sve što ste napisali u Javi možete prostim copy/paste prebaciti u Groovy. Ovo uključuje i sve Java biblioteke, tako da su u startu na raspolaganju sve dobre stvari na koje nas je Java navikla. Groovy naravno nije prosta kopija Jave, tako bi na primer Hello World program napisan u Groovy stilu izgledao ovako:
1 println "Hello world from Groovy"
|
Sam jezik ima mnogo zanimljivih mogućnosti, što je možda najlakše pokazati kroz par primera koji ilustruju lepe osobine Groovy sintakse. Pre nego što počnemo, skoknite do http://groovy.codehaus.org/Download, i ako želite instalirajte Groovy - instalacija nije velika, a uključuje sve potrebne stvari da bi mogli napisati i svoj prvi Groovy skript. Instalacija uključuje i alat GroovyConsole, koji izgleda ovako:
U gornjem delu ekrana pišete skript, dok se rezultati izvršavanja vide u donjem delu. Ako želite da koristite neku Java biblioteku, odgovarajući jar morate nekako staviti u classpath. Za početak je najzgodnije da koristite podrazumevani lib folder koji se nalazi (ili ga možete kreirati) u vašem home folderu - na linuksu bi to bilo „~/.groovy/lib/“ na windowsu „c:\documents and settings\sasas\.groovy\lib“. Kada u lib folder dodate novi fajl, potrebno je restartovati Groovy konzolu.
Konačno dolazimo do primera sintakse na kojima je moguće videti razlike između Java i Groovy koda.
Da bi se dobilo na agilnosti jezika, najčešće upotrebljavane klase se automatski importuju u svaki skript koji pišete:
Tako dosadni:
1 System.out.prinntln(„test“);
|
postaje:
1 prinntln(„test“);
|
Da ne govorimo o oslobađanju beskonačne gomile importa koje viđamo u gotovo svakoj klasi.
Groovy je dinamički tipiziran jezik, dakle nije potrebno eksplicitno navoditi tipove podataka prilikom deklaracije. Koliko puta ste bili u situaciji da u Javi napišete deklaraciju kao što je:
1 HttpSOAPConnectionFactory factory = new HttpSOAPConnectionFactory();
|
U Groovyju to možemo elegantnije i kraće napisati sa:
1 def factory = new HttpSOAPConnectionFactory();
|
Ipak, treba povesti računa da kad jednom promenjivoj dodelimo vrednost, njen tip nije moguće menjati, dakle ovaj kod bi proizveo grešku:
1 def name = "pera peric"
|
Time je programer zaštićen od fantomskih grešaka dodele tipičnih za jezike poput PHPa, jer ćete na loše dodele vrednosti biti upozoreni prilikom kompajliranja.
I u Javi i u Groovyju moguće je napisati sledeći izraz:
1 "ime".toUpperCase();
|
Dakle, i Java i Groovy string konstantu posmatraju kao objekat. Međutim u Groovyju je moguće napisati i izraz:
1 10.times();
|
To znači da su svi podaci u Groovyju objekti, i da se brojne ili boolean konstante u editoru tako i ponašaju. Jedan od efekata ovog dizajna je da ne postoji razlika između == i equals(). U Groovyju je uvedena konvencija da u svim slučajevima == znači isto što i equals().
Groovy stringovi u odnosu na Javu donose nekoliko značajnih poboljšanja. Pre svega, string konstante je moguće napisati na više načina:
1 def ime = 'pera'
|
Ukoliko string konstantu napišete unutar dvostrukih navodnika, u stvari deklarišete GString, i u tom slučaju moguće je u string direktno ubaciti promenjivu ili cele izraze, kao na primer:
1 def i = 1
|
Vredno je napomenuti da Groovy ima i mnogo zgodniju sintaksu za regularne izraze od Jave. Izrazi se definišu jednostavno:
1 def myRegex = /gr..vy/
|
Dakle, bilo koji tekst koji uokvirimo znakom „/“ se smatra regularnim izrazom. Operator ==~ označava jednakost stringa sa regularnim izrazom, dakle rezultat gornjeg programa bi bio „true“.
Kolekcije u Groovyju takođe imaju nekoliko sintaksnih prednosti u odnosu na Javu. Pre svega, liste i mape je dosta jednostavnije deklarisati:
1 def mylist = []
|
Dodavanje novih članova je takođe lakše:
1 mylist += "jedan"
|
Opsezi (ranges) su veoma zgodno proširenje klase java.util.List. Opsezi se deklarišu na sledeći način:
1 def inclusiveRange = 1..10
|
Opsezi mogu poslužiti za iteraciju kroz for petlju, što po mom subjektivnom osećaju mnogo pomaže u preglednosti napisanog koda, na primer:
1 for (i in 1..10) {
|
Closure možemo posmatrati kao anonimne metode na steroidima, s jedne strane mnogo upotrebljivije a ujedno i mnogo zgodnije za deklaraciju i manipulisanje.
U praksi to izgleda tako da možete napisati mali komadić koda koji je moguće proslediti funkciji ili dodeliti nekoj promenjivoj, čime kod postaje prvoklasni tip podataka.
Za ilustraciju, pogledajmo program u Javi koji filtrira listu stringova i ispisuje samo one koji odgovaraju kriterijumu:
01 import java.util.ArrayList;
|
Ovde možemo zgodno upotrebiti Closure, pa bi ekvivalentan Groovy kod izgledao ovako:
01 def gradovi = []
|
U primeru smo dakle metodi each() koja služi za iteraciju kroz listu prosledili kod koji će da sa svakim elementom nešto uradi. Gornji kod izgleda pomalo nezgrapno, jer se stalno morate podsećati da zatvorite i malu zagradu na kraju izraza. Zato postoji i specijalna sintaksa za pozivanje funkcija koje kao parametar zahtevaju closure – umesto da se closure piše unutar poziva funkcije, moguće ga je staviti posle poziva funkcije.
Takođe u specijalnom slučaju, ako imamo samo jedan parametar i nismo ga eksplicitno imenovali pomoću -> operatora, on dobija ime „it“ koje možemo koristiti unutar closurea.
Gornji primer bi se onda mogao napisati i kraće i logičnije:
1 gradovi.each() {
|
S obzirom da se lepa sintaksa i napredne mogućnosti jezika „ne mažu na 'leba“, pitanje je gde bi Java profesionalac mogao upotrebiti Groovy, odnosno kako upotrebiti jezik da se reše realni problemi na efikasniji način? Iz mog iskustva jezik se pokazao kao odlično rešenje u nekoliko slučajeva:
Na kraju, slobodno šaljite predloge i komentare o tome šta biste još u vezi Groovyja želeli da pročitate – potrudiću se da na sve komentare odgovorim, i svakako ću ih smatrati podsticajem za buduće tekstove o ovom stvarno zanimljivom jeziku.