GR8Conf 2009: Groovy Usage Patterns by Dierk König
-
date post
17-Oct-2014 -
Category
Entertainment & Humor
-
view
7.203 -
download
0
description
Transcript of 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
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
#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
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
#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
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
#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
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
#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
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
#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
#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
<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
<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
<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
<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
<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
#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
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
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
Pattern Summary
• Super Glue• Liquid Heart• Keyhole Surgery• Smart Configuration• Unlimited Openness• House-Elf Scripts• Prototype
Keep groovin' !
søndag den 17. maj 2009
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
Questions?
More patterns in the pipeline:
Lipstick - API enhancementsGhost - generating invisible code
<your suggestion here>
søndag den 17. maj 2009