Upload
ribomation
View
977
Download
2
Embed Size (px)
DESCRIPTION
This presentation (in Swedish) gives a gentle introduction to the programming langauge Groovy and the web framework Grails. It starts by setting the language into its context of language evolution in general and JVM languages in particular.
Citation preview
Vad är Groovy och Grails?
Jens RiboeSeptember 2009
i samarbete med
Vem är Jens Riboe?
För lite olika kunder
Varför?
Produktivitetsförbättring Development Speed Konstruktionstiden för en webbapplikation
med feature X Fem år sedan: 1-2 månader Idag: 1-2 dagar
Språkutvecklingen
Subroutine
Module
Class
Abstract data type
ObjectOriented
Programming
Functionalprogramming
1960 1970 1980 1990 2000 2010
DynamicLanguages
PragmaticFP & OOP
FortranCobol
Simula
ModulaPascalAda
MLSchemeHaskel
C++
JavaScript Ruby
GroovyJRubyScalaClojurePerl6
STL & JGL
Java
SmallTalk
LISPλ-kalkyl
ScriptLanguagesPerl
C
Objective-C
Perl5 PythonPHP
JVM blir en plattform för mer än Java
Nya språk ovanpå eller bredvid Java Använder JVM:en som exekveringsmaskin På sikt tonar Java bort såsom C gjorde när C+
+ kom
Domain
Special
General
JVM Språk
Scala Martin Odersky
École Polytechnique Fédérale de Lausanne (EPFL) 2004
Multi-paradigm Object-Oriented programming
Java + Mixin och Traits Functional programming
Closures och Pattern Matching Static typing
Kompilatorn hittar många fel Extendible
Lätt att skapa DSL
JRuby och Jython Många scriptspråk finns porterade till JVM:en JRuby är en portering av Ruby Jython är en portering av Python Ruby on Rails webbramverket var trigger
Skapade stort intresse för Rails som ramverk Ruby som språk
Clojure och Jaskel Renodlade functionella språk på JVM:en Clojure är en LISP variant Jaskel är en portering av Haskel
Groovy
Groovy James Strachan
2003 http://radio.weblogs.com/0112098/2003/08/29.html
Inspirerad av Ruby och Python Den 'naturliga' vidareutvecklingen av Java
Superset av Java Såsom C övergick i C++
Egenskaper Dynamiskt (duck typing) Objektorienterat (classes) Funktionellt (closures)
Bättre än Java Betydligt mindre text att skriva Duck typing Trevliga nya operatorer Closures Groovy beans Groovy string Regex Categories Operator overloading Builders Nya libs och tools kommer hela tiden
Duck typing If it walks like a duck and it quacks like a duck,
then it probably is as a duck Metodanrop på objekt utan krav på att tillhöra
viss typdef min(a, b) { a <= b ? a : b }
def aNumber = 17println "number: " + min(aNumber - 3, aNumber + 3)
def aString = 'foobar'println "string: " + min('xx' + aString, 'aa' + aString)
def aDate = new Date()println "date: " + min(aDate - 1, aDate + 1)
number: 14string: aafoobardate: Fri Sep 04 11:20:17 CEST 2009
Null catch operator ?.
if (user != null && user.getEmail() != null) { domain = user.getEmail().getDomain();}
domain = user?.email?.domain
I stället för
räcker det med
Elvis operator ?:
String h = System.getProperties.getProperty("user.home");dir = (home != null ? home : "/tmp");
dir = System.properties.'user.home' ?: '/tmp'
I stället för
räcker det med
println '-' * 20println "A) ${System.properties.'user.home' ?: '/tmp'}"println "B) ${System.properties.'user-home' ?: '/tmp'}"
--------------------A) C:\Users\jensB) /tmp
Spaceship operator <=>
List<Todo> todos = new ArrayList<Todo>();. . .Collections.sort(todos, new Comparator() { public int compare(Object o1, Object o2) { if (o1 instanceof Todo && o2 instanceof Todo) { Todo t1 = (Todo) o1; Todo t2 = (Todo) o2; return t1.deadline.compareTo(t2.deadline); } return 0; }});
def todos = [. . .]todos = todos.sort {t1, t2 -> t1.deadline <=> t2.deadline}
I stället för
räcker det med
Spread operator *.
List<String> txt = new ArrayList<String>();for (Todo t : todos) { txt.add(t.getText());}System.out.println("txt = " + txt);
def txt = todos*.textprintln txt
I stället för
räcker det med
List och Map och Range Del av språket List (java.util.*List) Map (java.util.*Map)
def lst = [17, 'foo', 'bar', 'fee']assert lst[0] == 17assert lst[-2] == 'bar'assert lst[1..2] == ['foo', 'bar']
def tbl = [one:1, two:2, three:3, four:4]assert tbl.one == 1assert tbl.four == 4
Closures Anonyma funktionsblock
def nums = (1..10)println numsprintln nums.collect {it * it}println nums.findAll {n -> n % 2}println nums.inject(0) {sum, n -> sum + n}
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10][1, 4, 9, 16, 25, 36, 49, 64, 81, 100][1, 3, 5, 7, 9]55
GroovyBeans
import java.util.Date;public class Todo { private String text; private Date deadline; public Todo(String t, Date d) {text=t; deadline=d;} public String getText() {return text;} public void setText(String t) {text=t;} public Date getDeadline() {return deadline;} public void setDeadline(Date d) {deadline=d;}};
class Todo { String text Date deadline}
I stället för
räcker det med
Användning av Groovy Beans
def t = new Todo(deadline: new Date() + 3, text: 'Fix that bug')t.text = 'Write that Groovy script'
def todos = [new Todo(text:'Skip Java'), new Todo(text:'Hack w Groovy'),
new Todo(text:'Web w Grails')]todos = todos.sort {t1,t2 -> t1.deadline <=> t2.deadline}
println todos*.text.join(".\n")
Skip Java.Hack w Groovy.Web w Grails
Categories Ett sätt att temporärt addera metoder till en
klass
import java.text.SimpleDateFormatclass FmtBoost { static String iso8601(Date self) { new SimpleDateFormat('yyyy-MM-dd').format(self) } static String getTraditional(Date self) { new SimpleDateFormat('d MMM yyyy').format(self) }}
def today = new Date()use (FmtBoost) { println "Today: ${today.iso8601()}" println "Today: ${today.traditional}"}
def today = new Date()println "Today: ${today}"println "Today: ${today.iso8601()}"
Today: Sat Sep 05 14:19:13 CEST 2009 …MissingMethodException: No signature of method: java.util.Date.iso8601()…
Today: 2009-09-05Today: 5 sep 2009
Användning av FmtBoostclass Doit { String text Date deadline = new Date()}
def lst = [ new Doit(text: 'Read that groovy book'), new Doit(text: 'Start using builders'), new Doit(text: 'Investigate groovy xml')]
int day = 1lst.each {it.deadline += day++}
use (FmtBoost) { lst.each {println "${it.deadline.traditional}: ${it.text}"}}
6 sep 2009: Read that groovy book7 sep 2009: Start using builders8 sep 2009: Investigate groovy xml
Builders Kombination av closures och meta-
programmering Inkrementell konstruktion av composite
structures Exempel
XML och HTML Swing Ant
Generera XML
use(FmtBoost) { def buf = new StringWriter() def xml = new MarkupBuilder(buf) xml.'doit-list' { lst.each { doit(deadline: it.deadline.iso8601(), it.text) } } println buf}
<doit-list> <doit deadline='2009-09-06'>Read that groovy book</doit> <doit deadline='2009-09-07'>Start using builders</doit> <doit deadline='2009-09-08'>Investigate groovy xml</doit></doit-list>
Processa XMLdef news(url, phrase) { def items = new XmlParser().parse(url).channel.item if (phrase) { items = items.grep { it.title.text().contains(phrase) } } items.collect {n -> [ title: n.title.text() - "\n", date: n.pubDate.text(), url: n.link.text(), text: n.description.text() ]}}
<?xml version="1.0" ?><rss> <channel> <title>Yahoo! News</title> <item> <title>Fox adds on-air tweets to ...</title> <link>http://...</link> <pubDate>Fri, 04 Sep 2009 02:54:51 GMT</pubDate> <description>Summer reruns are ...</description> </item> <item>...</item> <item>...</item> </channel></rss>
Result av news(url, phrase)def lst = news('http://rss.news.yahoo.com/rss/tech', 'Google')
lst.each { it.text = it.text.replaceAll('<br clear="all"/>', '') it.text = it.text.replaceAll(/(<p>)|(<\/p>)/, '') it.text = it.text.replaceAll(/<a href.+<\/a>/, '')}
lst.each { println "** ${it.text.substring(0,60)}\n ${it.date}"}
** AP - The executive who led Google Inc.'s expansion in China Fri, 04 Sep 2009 06:25:08 GMT** AP - The final assault on a class-action settlement that wou Thu, 03 Sep 2009 23:30:27 GMT
Groovy ökar produktiviteten Write less, but gain more Kraftfulla verktyg
Operators, operator-overloading, regex, categories, builders, meta-programming, groovy strings, groovy beans, . . .
Kraftfulla bibliotek GAnt, Griffon, GORM, Grails, . . .
Grails
Grails Oblyg 'stöld' och förbättring av 'Ruby on Rails' Convention over Configuration Automatisk lagring av domänobjekt
Groovy-fiering av Spring Framework och Hibernate Generering av boilerplate kod
Scaffolding and Templating Byggnadsställningar och mallar
GSP = Groovy Server Pages Många plug-ins
Convention over Configuration
Genom att placera groovy klasser i olika filkataloger, så behandlas de på olika sätt
Domain
class Person { String name, email, mobile Location location}
class Location { String name String street, zip, city = 'Stockholm', country = 'Sweden' float latitude, longitude}
Hanteras av
Hibernate & Spring
def person = Person.get(17)def lastName = "Riboe"person.email = "${person.name}@${domain}"person.save()
def sthPlaces = Location.findByCity('Stockholm')
Relation
Dynamiska DAO
funktioner
Controller
class AjaxController { String JSON = 'application/json' def getDB = {...} def savePerson = { Person person = Person.get( params.personId ) ... render(contentType:JSON, text: person as JSON) } def saveLocation = {...} def removePerson = {...} def removeLocation = {...}}
http://server/BuddyMap/ajax/savePerson?personId=17&name=...
Serviceclass NewsService { boolean transactional = true
def load(url, phrase) { def items = new XmlParser().parse(url).channel.item if (phrase) { items = items.grep { it.title.text().contains(phrase) } } items.collect { [title:it.title.text(), date:it.pubDate.text(), url: n.link.text(), …] } }}
class NewsController { def newsService
def index = { redirect(action: list) }
def list = { def url = 'http://rss.news.yahoo.com/rss/' def news = newsService.load(url, params.phrase) [news: news, phrase: params.phrase,] } }
Dependency
Injection
View Model
Transactionjmf
State-less SessionBean
View (GSP)<%@ page contentType="text/html;charset=UTF-8" %><html><head> <title>News</title> <meta name="layout" content="main" /></head><body> <h1>Some News</h1> <ul> <g:each in="${news}"> <li> <b><a href="${it.url}">${it.title}</a></b><br/> <i>${it.date}</i><br/> ${it.text} </li> </g:each> </ul></body></html>
View Model
Layout (SiteMesh)<html><head> <title>ToDo » <g:layoutTitle default="Welcome"/></title> <link rel="stylesheet" href="${resource(dir:'css',file:'todo.css')}" /> <g:layoutHead /> <g:javascript library="application" /></head><body> <div> <div id="hd"> <a id="logoTxt" href="<g:createLinkTo dir="/"/>">ToDo</a> </div> <div id="bd"><g:layoutBody/></div> <div id="ft"> <div id="footerText">ToDo - A small Grails demo webapp</div> </div> </div></body></html>
Resultatet
Mera Info
Webbapplikationer med Groovy och Grails
Dag 1: Grundläggande GroovyDag 2: Avancerad GroovyDag 3: Kickstart med GrailsDag 4: Avancerad Grails
Sammanfattning Groovy kommer gradvis ersätta Java
Closures kommer att finnas i alla (moderna) språk Builders och meta-programmering
Grails skapar snabbt nya webbapplikationer Convention over Configuration Spring & Hibernate GSP
Frågor?