24
Seven Groovy usage patterns for Java developers Dierk König [email protected] søndag den 17. maj 2009

GR8Conf 2009: Groovy Usage Patterns by Dierk König

  • View
    7.203

  • Download
    0

Embed Size (px)

DESCRIPTION

Dierk König, author of Groovy in Action, guides attendees through the presentation of 7 key Groovy usage patterns

Citation preview

Page 1: GR8Conf 2009: Groovy Usage Patterns by Dierk König

Seven Groovy usage patterns for Java developers

Dierk Kö[email protected]

søndag den 17. maj 2009

Page 2: GR8Conf 2009: Groovy Usage Patterns by Dierk König

Welcome!

Dierk KönigCanoo fellow, www.canoo.com Rich Internet Applications

Committer to Groovy and GrailsAuthor: Groovy in Action

søndag den 17. maj 2009

Page 3: GR8Conf 2009: Groovy Usage Patterns by Dierk König

The 7 usage patterns

• Super Glue• Liquid Heart• Keyhole Surgery• Smart Configuration• Unlimited Openness• House-Elf Scripts• Prototype

Examples in Groovy

søndag den 17. maj 2009

Page 4: GR8Conf 2009: Groovy Usage Patterns by Dierk König

#1 Super Glue

• Build application from existing building blocks

• Java makes perfect infrastructure: middleware, frameworks, widget sets, services

• Scripting makes a flexible (agile) applikation layer: views und controller

• Grails, GSP, JBoss Seam, WebWork, Struts 2 Actions,...• Example: combination of XML parser, Java networking

and Swing widget set in order to build a standard RSS feed reader

søndag den 17. maj 2009

Page 5: GR8Conf 2009: Groovy Usage Patterns by Dierk König

def url ='http://www.groovyblogs.org/feed/rss'def items = new XmlParser().parse(url).channel.itemdef cols = 'pubDate title description'.tokenize()

groovy.swing.SwingBuilder.build { frame(id:'f', title: 'Groovy Blogs', visible:true) { scrollPane { table { tableModel(list: items) { cols.each { col -> closureColumn header: col, read: { it[col].text() } } } } } } f.pack()}

Super Glue example: RSS Reader

søndag den 17. maj 2009

Page 6: GR8Conf 2009: Groovy Usage Patterns by Dierk König

#2 Liquid Heart

• Externalize business models

• Given application structure in Java• Allow to learn about the business:

keep entities, relations, and behaviour flexible through scripting

• Usages: Spring beans, JBoss components,rule engines (groovyrules.dev.java.net, JSR-94), Grails,enterprise risk management for world-leading insurances

• Example: calculation rules for bonus allocation

søndag den 17. maj 2009

Page 7: GR8Conf 2009: Groovy Usage Patterns by Dierk König

revenue = employee.revenueswitch(revenue / 1000) { case 0..100 : return revenue * 0.04 case 100..200 : return revenue * 0.05 case {it > 200} : bonusClub.add(employee) return revenue * 0.06}

Liquid Heart example: bonus allocation

Binding binding = new Binding();binding.setVariable("employee", employee);binding.setVariable("bonusClub", bonusClub);GroovyShell shell = new GroovyShell(binding);File script = new File(filename);float bonus = (float) shell.evaluate(script);

søndag den 17. maj 2009

Page 8: GR8Conf 2009: Groovy Usage Patterns by Dierk König

#3 Keyhole Surgery

• Minimal-invasive surgery "in vivo"

• Lots of need for runtime inspection and modifications

• Ad-hoc queries are not foreseeable• "Backdoor" for the live execution of scripts• Particularly useful for

product support, failure analysis, hot fixes, emergencies• Usages: Oracle JMX Beans, XWiki, SnipSnap, Ant, Canoo

WebTest, Grails Console, GAE, ULC Admin Console• Example: a live Groovy Servlet

søndag den 17. maj 2009

Page 9: GR8Conf 2009: Groovy Usage Patterns by Dierk König

def ds = Config.dataSourceds.connection = new DebugConnection(ds.connection)

Surgery through a Servlet keyhole

users = servletContext.getAttribute('users')bad = users.findAll { user -> user.cart.items.any { it.price < 0 } }servletContext.setAttribute('users', users - bad)

Problems with the database connection?

Remove malicious users from the servlet context

søndag den 17. maj 2009

Page 10: GR8Conf 2009: Groovy Usage Patterns by Dierk König

#4 Smart Configuration

• Enhance configuration with logic

• Replace dumb XML configs• Use references, loops, conditionals, inheritance, execution

logic, runtime environment adaption, ... • Typical scenario for domain specific languages (DSLs),

Groovy Builder, Grails plugins, product customization,Groovy for OpenOffice: Community Innovation Program Silver Award Winner

• Example: Navis SPARCS N4

søndag den 17. maj 2009

Page 11: GR8Conf 2009: Groovy Usage Patterns by Dierk König

def ensureEvent = { change -> if (! event.getMostRecentEvent(change) { event.postNewEvent(change) }}

switch (event.REROUTE_CTR) { case 'OutboundCarrierId' :

ensureEvent('CHANGE_VSL') break case 'POD' : if (! event.CHANGE_VSL) ensureEvent('CHANGE_POD') break

}

Smart Config example: container routing

søndag den 17. maj 2009

Page 12: GR8Conf 2009: Groovy Usage Patterns by Dierk König

#5 Unlimited Openness

• Every line of code may be changed

• It's impossible (and not desirable!) to design for every possible future requirement

• Allow for easily changing the code without tedious setup for compilation and deployment

• Follow the lessons of Perl, PHP, Python,...

• Example: groovyblogs.org, PillarOne

søndag den 17. maj 2009

Page 13: GR8Conf 2009: Groovy Usage Patterns by Dierk König

#6 House Elf

• Delegate the housework

• Build automation, continuous integration, deployment, installer, service monitoring, reports, statistics, automated documentation, functional tests, HTML scraping, Web remote control, XML-RPC, WebServices

• Usages with Ant, Maven, AntBuilder, Gant, Gradle, Canoo WebTest, Grails scaffolding, ...

• Examples: hooking scripts into Ant

søndag den 17. maj 2009

Page 14: GR8Conf 2009: Groovy Usage Patterns by Dierk König

<groovy>import org.apache.tools.ant.*import org.jfugue.*project.addBuildListener(new PlayListener())class PlayListener implements BuildListener { def play = { new Player().play(new Pattern(it)) } void buildStarted(event) { } void buildFinished(event) { } void messageLogged(event) { } void targetStarted(event) { play("D E") } void targetFinished(event) { play("C5maj") } void taskStarted(event) { } void taskFinished(event) { }}</groovy>

House Elf: musical Ant

søndag den 17. maj 2009

Page 15: GR8Conf 2009: Groovy Usage Patterns by Dierk König

<groovy>import org.apache.tools.ant.*import org.jfugue.*project.addBuildListener(new PlayListener())class PlayListener implements BuildListener { def play = { new Player().play(new Pattern(it)) }

void targetStarted(event) { play("D E") } void targetFinished(event) { play("C5maj") }

}</groovy>

House Elf: musical Ant

søndag den 17. maj 2009

Page 16: GR8Conf 2009: Groovy Usage Patterns by Dierk König

<groovy>import org.apache.tools.ant.*import org.jfugue.*

def play = { new Player().play(new Pattern(it)) }

void targetStarted(event) { play("D E") } void targetFinished(event) { play("C5maj") }

project.addBuildListener(player as BuildListener)}</groovy>

House Elf: musical Ant

søndag den 17. maj 2009

Page 17: GR8Conf 2009: Groovy Usage Patterns by Dierk König

<groovy>import org.apache.tools.ant.*import org.jfugue.*

def play = { new Player().play(new Pattern(it)) }

def player = [ targetStarted: { play("D E") }, targetFinished: { play("C5maj") } ]project.addBuildListener(player as BuildListener)}</groovy>

House Elf: musical Ant

søndag den 17. maj 2009

Page 18: GR8Conf 2009: Groovy Usage Patterns by Dierk König

<groovy>import org.apache.tools.ant.*import org.jfugue.*

def play = { new Player().play(new Pattern(it)) }def player = [ targetStarted : { play "D E" }, targetFinished : { play "C5maj" } ]project.addBuildListener(player as BuildListener)}</groovy>

House Elf: musical Ant

søndag den 17. maj 2009

Page 19: GR8Conf 2009: Groovy Usage Patterns by Dierk König

#7 Prototype

• Feasibility study on the target platform

• "Spikes" for technological or algorithmic ideas with more expressiveness, quicker feedback, and enhanced analysis capabilities

• Later port to Java is optional• Usages: early user feedback about the domain model

through a functional Grails prototype, algorithms for image manipulation

• Example: prime number disassembly

søndag den 17. maj 2009

Page 20: GR8Conf 2009: Groovy Usage Patterns by Dierk König

boolean isPrime(x) { return ! (2..<x).any { y -> x % y == 0 } }

int primeBelow(x) { (x..1).find { isPrime(it) } }

List primeFactors(x) { if (isPrime(x)) return [x] int p = primeBelow(x) while (p > 1) { if (x % p == 0) return [p, *primeFactors(x.intdiv(p))] p = primeBelow(p-1) } }

for (n in 100..110) { println "$n : "+primeFactors(n)}

Prototype example: prime numbers

søndag den 17. maj 2009

Page 21: GR8Conf 2009: Groovy Usage Patterns by Dierk König

class ModCountCategory { static int count = 0 static int mod(Integer self, Integer argument) { count++ return self - argument * self.intdiv(argument) } }

use (ModCountCategory) { for (n in 1000..1010) { ModCountCategory.count = 0 factors = primeFactors(n) println "$n : $factors".padRight(30) + "(in " + "${ModCountCategory.count}".padLeft(5) + " steps)" assert n == factors.inject(1){result, item -> result *= item }} }

Prime numbers: counting modulo ops

søndag den 17. maj 2009

Page 22: GR8Conf 2009: Groovy Usage Patterns by Dierk König

Pattern Summary

• Super Glue• Liquid Heart• Keyhole Surgery• Smart Configuration• Unlimited Openness• House-Elf Scripts• Prototype

Keep groovin' !

søndag den 17. maj 2009

Page 23: GR8Conf 2009: Groovy Usage Patterns by Dierk König

More Information

• Groovy in Action groovy.canoo.com/gina Manning, 2007, Foreword by James GoslingKönig mit Glover, Laforge, King, Skeet

• groovy.codehaus.org, grails.orggroovyblogs.org, searchgroovy.org

søndag den 17. maj 2009

Page 24: GR8Conf 2009: Groovy Usage Patterns by Dierk König

Questions?

More patterns in the pipeline:

Lipstick - API enhancementsGhost - generating invisible code

<your suggestion here>

søndag den 17. maj 2009