About
fv_2007
Agile innovative developer with deep insight into lots of platforms, technologies and protocols. Absolute “early adopter” in Web 2.0 technologies and more. Large professional network and eagerly talking about architecture, strategy, design patterns, restful ressources, object-oriented thinking and modeling languages such as PML. Special interest in programminglanguages constructs, knowledge on languages like Smalltalk, Erlang, Java, Clojure, Scala, Ruby... read more
Comments
Language

A Groovy Switch September 10, 2008 05:46 over 3 years ago

Dynamiske sprog som ruby og groovy fylder mere og mere i min hverdag. Mange af mine kollegaer er ikke glade for de typeløse konstruktioner men for mig er det vejen frem og mit hoved arbejder godt uden faste rammer. Jamen hvad med compile check? Ja indrømmet at man nok vil foretrække dygtige kompetente folk, men sådan er det jo altid. I mit professionelle arbejde bruger jeg ofte dynamiske sprog til prototying og sandboxing af komplekse problemerstillinger.

Fx at mappe nogle nøgler til nogle roller. Helt basalt. Løsningen er implementeret i Java BIG scale. Jeg skrev den første gang kode mens en pensionskyndig sad og forklarede reglerne. Koden ente op i en lang switch statement som jeg ikke var særlig tilfreds med og jeg kunne ikke på en enkelt måde vise kunden hvad jeg var kommet frem til.

Protyping med groovy er super. Man kan lave datastrukturer på kort tid og opnå en reaktion med det samme. Da vi vidste at vi skulle mappe nøgler til værdier begyndte jeg med en hash.

def roles = [
        1: 'Omregning',
        2: 'Garanti',
        3: 'Garanti',
        4: 'Garanti',
        10: 'Omregning',
        20: 'Omregning',
        30: 'Garanti',
        40: 'Omregning'
    ]   

Hvis man kan udtrykke regler som datastrukturer er det perfekt. Man kan derefter overveje hvilken form for traversering af regler man vil benytte. Man for isoleret(isolation) den kode som utrykker regler fra den kode som aflæser(delegation) regler.

For at gøre det hele lidt mere spændende vil jeg gerne kunne mappe begge vejen, altså både fra nøgle til værdi og fra værdi til nøgler. Det kan nemlig lade sig gøre i en og samme metode. Det er også vigtigt at alle forespørgsler som ikke er en del af data skal fejle.

Metoden modtager en besked med et argument. Argumentet løber gennem switchen og bliver derefter checket hvorvidt nøglen eksisterer, hvis ja findes værden. I anden tilfælde modtages værdien og denne gang respondere switchen ved at løbe værdierne gennem og returner alle de nøgler som kan relateres til argumentet.

/** map role back and   */
def map(x) {
    switch (x)  {
       case roles.keySet() : return roles.get(x); break
       case roles.values() : return roles.findAll{ it.value == x } ; break
       default: throw new RuntimeException("Unknown token on ${x}")
    }
}

Switch på typeløse X. Groovy understøtter også Ranges i cases. (range = 5..8). Så når der står case roles.ketSet er den range der checkes for de nøgler som findes i hash’en roles.

Super nice. Er det farligt? Overhoved ikke. Fylder det mindre en tilsvarende i Java? Ja, betydeligt. Er det svært at læse? Nej. Er hastigheden væsentligt nedsat? Måske. Er det nemmere at vedligeholde? Ja, netop derfor gad jeg bruge ekstra tid på det nu! For jeg kommer ikke tilbage.


By Frank Vilhelmsen - 1 tag: groovy - Add comment