groovy vs boilerplate and ceremony code
TRANSCRIPT
![Page 1: Groovy vs Boilerplate and Ceremony Code](https://reader036.vdocument.in/reader036/viewer/2022062319/5558766dd8b42a8d018b530b/html5/thumbnails/1.jpg)
JVM. quack() or Groovy vs Ceremony
![Page 2: Groovy vs Boilerplate and Ceremony Code](https://reader036.vdocument.in/reader036/viewer/2022062319/5558766dd8b42a8d018b530b/html5/thumbnails/2.jpg)
…
Stas ShevchenkoJava Launch, 23/04/2013, Riga
![Page 3: Groovy vs Boilerplate and Ceremony Code](https://reader036.vdocument.in/reader036/viewer/2022062319/5558766dd8b42a8d018b530b/html5/thumbnails/3.jpg)
Java Language comes with
• Design Patterns• Boilerplate• Overly Ceremony code
![Page 4: Groovy vs Boilerplate and Ceremony Code](https://reader036.vdocument.in/reader036/viewer/2022062319/5558766dd8b42a8d018b530b/html5/thumbnails/4.jpg)
1. Patterns
…
![Page 5: Groovy vs Boilerplate and Ceremony Code](https://reader036.vdocument.in/reader036/viewer/2022062319/5558766dd8b42a8d018b530b/html5/thumbnails/5.jpg)
Boilerplate
![Page 6: Groovy vs Boilerplate and Ceremony Code](https://reader036.vdocument.in/reader036/viewer/2022062319/5558766dd8b42a8d018b530b/html5/thumbnails/6.jpg)
2. Boilerplate
- getter/setters- Lazy init factories- toString, hashCode, equals- Explicit Exception declaration/handling- Close for resources- synchronization
![Page 7: Groovy vs Boilerplate and Ceremony Code](https://reader036.vdocument.in/reader036/viewer/2022062319/5558766dd8b42a8d018b530b/html5/thumbnails/7.jpg)
Ceremony: Code’s Worst Enemy
![Page 8: Groovy vs Boilerplate and Ceremony Code](https://reader036.vdocument.in/reader036/viewer/2022062319/5558766dd8b42a8d018b530b/html5/thumbnails/8.jpg)
Code Today (Death Star)
CEREMONY
ESSENCE
![Page 9: Groovy vs Boilerplate and Ceremony Code](https://reader036.vdocument.in/reader036/viewer/2022062319/5558766dd8b42a8d018b530b/html5/thumbnails/9.jpg)
Future: Paradigm, Languages, Frameworks
CEREMONY
ESSENCE
![Page 10: Groovy vs Boilerplate and Ceremony Code](https://reader036.vdocument.in/reader036/viewer/2022062319/5558766dd8b42a8d018b530b/html5/thumbnails/10.jpg)
3. Ceremony to Essence code. Step 0
public ActionForward edit(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { PersonForm personForm = (PersonForm) form; if (personForm.getId() != null) { PersonManager mgr = (PersonManager) getBean("personManager"); Person person = mgr.getPerson(personForm.getId()); personForm = (PersonForm) convert(person); updateFormBean(mapping, request, personForm); } return mapping.findForward("edit"); }
![Page 11: Groovy vs Boilerplate and Ceremony Code](https://reader036.vdocument.in/reader036/viewer/2022062319/5558766dd8b42a8d018b530b/html5/thumbnails/11.jpg)
Step 1. Duck Typing
edit(mapping, form, request, response) throws Exception { personForm = form; if (personForm.getId() != null) { mgr = getBean("personManager"); person = mgr.getPerson(personForm.getId()); personForm = convert(person); updateFormBean(mapping, request, personForm); } return mapping.findForward("edit"); }
![Page 12: Groovy vs Boilerplate and Ceremony Code](https://reader036.vdocument.in/reader036/viewer/2022062319/5558766dd8b42a8d018b530b/html5/thumbnails/12.jpg)
Step 2. duck typing, without local variable
edit(mapping, form, request, response) throws Exception { if (form.getId() != null) { mgr = getBean("personManager"); person = mgr.getPerson(form.getId()); form = convert(person); updateFormBean(mapping, request, form); } return mapping.findForward("edit"); }
![Page 13: Groovy vs Boilerplate and Ceremony Code](https://reader036.vdocument.in/reader036/viewer/2022062319/5558766dd8b42a8d018b530b/html5/thumbnails/13.jpg)
Step 3. Implicit return, exceptions
edit(mapping, form, request, response) { if (form.getId() != null) { mgr = getBean("personManager"); person = mgr.getPerson(form.getId()); form = convert(person); updateFormBean(mapping, request, form); } mapping.findForward("edit"); }
![Page 14: Groovy vs Boilerplate and Ceremony Code](https://reader036.vdocument.in/reader036/viewer/2022062319/5558766dd8b42a8d018b530b/html5/thumbnails/14.jpg)
Step 4. Don't add a manager layer to MVC (yet). KISS + YAGNI.
edit(mapping, form, request, response) { if (form.getId() != null) { person = Person.find(form.getId()); form = convert(person); updateFormBean(mapping, request, form); } mapping.findForward("edit"); }
![Page 15: Groovy vs Boilerplate and Ceremony Code](https://reader036.vdocument.in/reader036/viewer/2022062319/5558766dd8b42a8d018b530b/html5/thumbnails/15.jpg)
Step 5. Conditionals make code expensive to test
edit(mapping, form, request, response) { person = Person.find(form.getId()); form = convert(person); updateFormBean(mapping, request, form); mapping.findForward("edit"); }
![Page 16: Groovy vs Boilerplate and Ceremony Code](https://reader036.vdocument.in/reader036/viewer/2022062319/5558766dd8b42a8d018b530b/html5/thumbnails/16.jpg)
Step 6. All action methods have the same four arguments
edit() { person = Person.find(form.getId()); form = convert(person); updateFormBean(mapping, request, form); mapping.findForward("edit"); }
![Page 17: Groovy vs Boilerplate and Ceremony Code](https://reader036.vdocument.in/reader036/viewer/2022062319/5558766dd8b42a8d018b530b/html5/thumbnails/17.jpg)
Step 7. Delegate object showing to form
edit() { person = Person.find(form.getId()); mapping.findForward("edit"); }
![Page 18: Groovy vs Boilerplate and Ceremony Code](https://reader036.vdocument.in/reader036/viewer/2022062319/5558766dd8b42a8d018b530b/html5/thumbnails/18.jpg)
Step 8. Standard routing
edit() { person = Person.find(form.getId()); }
Or Rubydef edit @person = Person.find(params[:id]) end
![Page 19: Groovy vs Boilerplate and Ceremony Code](https://reader036.vdocument.in/reader036/viewer/2022062319/5558766dd8b42a8d018b530b/html5/thumbnails/19.jpg)
Java Word
IoCAspectsLombok or Eclipse XtendCode generators -> Spring Roo
![Page 20: Groovy vs Boilerplate and Ceremony Code](https://reader036.vdocument.in/reader036/viewer/2022062319/5558766dd8b42a8d018b530b/html5/thumbnails/20.jpg)
JVM Languages
ClojureScala
GroovyJRubyJython
Java Script
![Page 21: Groovy vs Boilerplate and Ceremony Code](https://reader036.vdocument.in/reader036/viewer/2022062319/5558766dd8b42a8d018b530b/html5/thumbnails/21.jpg)
Clojure- Lisp – WTF?- By default Functional Programming only
![Page 22: Groovy vs Boilerplate and Ceremony Code](https://reader036.vdocument.in/reader036/viewer/2022062319/5558766dd8b42a8d018b530b/html5/thumbnails/22.jpg)
Scala- Syntax WTF- Acclimatization period 6 to 12 months
![Page 23: Groovy vs Boilerplate and Ceremony Code](https://reader036.vdocument.in/reader036/viewer/2022062319/5558766dd8b42a8d018b530b/html5/thumbnails/23.jpg)
JRuby- Ruby guys - gemns hell
![Page 24: Groovy vs Boilerplate and Ceremony Code](https://reader036.vdocument.in/reader036/viewer/2022062319/5558766dd8b42a8d018b530b/html5/thumbnails/24.jpg)
Jython- Python syntax ((
![Page 25: Groovy vs Boilerplate and Ceremony Code](https://reader036.vdocument.in/reader036/viewer/2022062319/5558766dd8b42a8d018b530b/html5/thumbnails/25.jpg)
Java Script (Rhino)- Is Java Script
![Page 26: Groovy vs Boilerplate and Ceremony Code](https://reader036.vdocument.in/reader036/viewer/2022062319/5558766dd8b42a8d018b530b/html5/thumbnails/26.jpg)
Starting Groovy
1. Download the .zip file from http://groovy.codehaus.org and unzip it to local drive
2. Create the GROOVY_HOME environment variable and add $GROOVY_HOME/bin to you path
3. type groovy -version
![Page 27: Groovy vs Boilerplate and Ceremony Code](https://reader036.vdocument.in/reader036/viewer/2022062319/5558766dd8b42a8d018b530b/html5/thumbnails/27.jpg)
Groovy Console
![Page 28: Groovy vs Boilerplate and Ceremony Code](https://reader036.vdocument.in/reader036/viewer/2022062319/5558766dd8b42a8d018b530b/html5/thumbnails/28.jpg)
Primitives
3.times { println it }
assert (10 instanceof Integer)
println 4.4.class
String s = 10 as String;println s;
![Page 29: Groovy vs Boilerplate and Ceremony Code](https://reader036.vdocument.in/reader036/viewer/2022062319/5558766dd8b42a8d018b530b/html5/thumbnails/29.jpg)
Groovy Beans
class Customer { Integer id def name Date dob}
def customer = new Customer(id:1, name:"Gromit", dob:new Date())
![Page 30: Groovy vs Boilerplate and Ceremony Code](https://reader036.vdocument.in/reader036/viewer/2022062319/5558766dd8b42a8d018b530b/html5/thumbnails/30.jpg)
Collections – Lists, Ranges
def list = [5, 6, 7, 8]assert list[2] == 7assert list instanceof java.util.List
def range = 5..8assert range.size() == 4assert range[2] == 7assert range instanceof java.util.List
![Page 31: Groovy vs Boilerplate and Ceremony Code](https://reader036.vdocument.in/reader036/viewer/2022062319/5558766dd8b42a8d018b530b/html5/thumbnails/31.jpg)
Collections - Map
def map = [name:"Gromit", likes:"cheese", id:1234]assert map["name"] == "Gromit"assert map['id'] == 1234assert map instanceof java.util.Map
![Page 32: Groovy vs Boilerplate and Ceremony Code](https://reader036.vdocument.in/reader036/viewer/2022062319/5558766dd8b42a8d018b530b/html5/thumbnails/32.jpg)
Collections features
assert [1, 3, 5] == ['a', 'few', 'words']*.size()
def words = ['ant', 'buffalo', 'cat', 'dinosaur']assert words.findAll{ w -> w.size() > 4 } == ['buffalo', 'dinosaur']
def words = ['ant', 'buffalo', 'cat', 'dinosaur']assert words.collect{ it[0] } == ['a', 'b', 'c', 'd']
def sub = list[1, 3, 20..25, 33]assert sub == [101, 103, 120, 121, 122, 123, 124, 125, 133]
![Page 33: Groovy vs Boilerplate and Ceremony Code](https://reader036.vdocument.in/reader036/viewer/2022062319/5558766dd8b42a8d018b530b/html5/thumbnails/33.jpg)
Duck typing
// Hey duckDuck myDuck = new Duck()myDuck.quack()
// Hey quackerdef duck = new Duck()myDuck.quack()
![Page 34: Groovy vs Boilerplate and Ceremony Code](https://reader036.vdocument.in/reader036/viewer/2022062319/5558766dd8b42a8d018b530b/html5/thumbnails/34.jpg)
Duck typing 2
class Duck { def quack() {println("quack")}}
def action = "quack"def duck = new Duck()duck."${action}"()
![Page 35: Groovy vs Boilerplate and Ceremony Code](https://reader036.vdocument.in/reader036/viewer/2022062319/5558766dd8b42a8d018b530b/html5/thumbnails/35.jpg)
Operators
a == b a.equals(b)a + b a.plus(b)a - b a.minus(b)a++ a.next()a << b a.leftShift(b)
def groovy = [”beer", ”rock&roll"]groovy << ”girls"
![Page 36: Groovy vs Boilerplate and Ceremony Code](https://reader036.vdocument.in/reader036/viewer/2022062319/5558766dd8b42a8d018b530b/html5/thumbnails/36.jpg)
Closures
def squareClosure = { value -> value * value;}
assert (4 == squareClosure(2))
![Page 37: Groovy vs Boilerplate and Ceremony Code](https://reader036.vdocument.in/reader036/viewer/2022062319/5558766dd8b42a8d018b530b/html5/thumbnails/37.jpg)
IO
def file = new File(sms.txt).eachLine{ println it }
file.write(”rewrite file”)
file.append(“add to file”)file << ”sexy style"
![Page 38: Groovy vs Boilerplate and Ceremony Code](https://reader036.vdocument.in/reader036/viewer/2022062319/5558766dd8b42a8d018b530b/html5/thumbnails/38.jpg)
XML
def xml = new groovy.xml.MarkupBuilder()xml.goods(type:”current”){ good(“Beer”) good (“Rock&Roll”) good (“Girls”)}
![Page 39: Groovy vs Boilerplate and Ceremony Code](https://reader036.vdocument.in/reader036/viewer/2022062319/5558766dd8b42a8d018b530b/html5/thumbnails/39.jpg)
XML
def goods = new XmlSlurper().parseText(…)def allGoods = records.nameassert 3 == allRecords.size()def allNodes = goods.depthFirst().collect{ it }def firstGood = goods.name[0]assert ’sms’ == firstGood .name()assert ‘Text’ == [email protected]()
![Page 40: Groovy vs Boilerplate and Ceremony Code](https://reader036.vdocument.in/reader036/viewer/2022062319/5558766dd8b42a8d018b530b/html5/thumbnails/40.jpg)
DSL
This is a really cool topic, where the stars are began…
• A DSL allows expressions in a domain specific manner
• Method pointers make this easy:def list = []def insert = list.&addinsert ”beer"insert ”rock&roll"
![Page 41: Groovy vs Boilerplate and Ceremony Code](https://reader036.vdocument.in/reader036/viewer/2022062319/5558766dd8b42a8d018b530b/html5/thumbnails/41.jpg)
Something to read
Groovy++Grails -> GORMGradle
![Page 42: Groovy vs Boilerplate and Ceremony Code](https://reader036.vdocument.in/reader036/viewer/2022062319/5558766dd8b42a8d018b530b/html5/thumbnails/42.jpg)
At the end – NPE fighter in my team
infringementAction.setCustomsOffice( versionedReplyInf != null ? (versionedReplyInf.getReplyInf() != null ? (versionedReplyInf.getReplyInf().getInf() != null ? (versionedReplyInf.getReplyInf().getInf().getInf() != null ? (versionedReplyInf.getReplyInf().getInf().getInf().
getCustomsOffice() != null ? versionedReplyInf.getReplyInf().getInf().getInf().
getCustomsOffice() : null) : null) : null) : null) : null);
![Page 43: Groovy vs Boilerplate and Ceremony Code](https://reader036.vdocument.in/reader036/viewer/2022062319/5558766dd8b42a8d018b530b/html5/thumbnails/43.jpg)
At the end on Groovy
Safe navigation operator “?.”
infringementAction.setCustomsOffice(versionedReplyInf?.getReplyInf()?.getInf()?.getInf()?.getCustomsOffice())