JVM. quack() or Groovy vs Ceremony
…
Stas Shevchenko
Java Launch, 23/04/2013, Riga
Java Language comes with
• Design Patterns
• Boilerplate
• Overly Ceremony code
1. Patterns
…
Boilerplate
2. Boilerplate
-   getter/setters
-   Lazy init factories
-   toString, hashCode, equals
-   Explicit Exception declaration/handling
-   Close for resources
-   synchronization
Ceremony: Code’s Worst Enemy
Code Today (Death Star)


               ESSENCE




      CEREMONY
Future: Paradigm, Languages,
         Frameworks

 CEREMONY




            ESSENCE
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");
 }
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");
}
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");
}
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");
}
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");
 }
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");
 }
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");
}
Step 7. Delegate object showing to
                 form
edit() {
  person = Person.find(form.getId());
  mapping.findForward("edit");
}
Step 8. Standard routing
edit() {
  person = Person.find(form.getId());
}

Or Ruby
def edit
  @person = Person.find(params[:id])
 end
Java Word
IoC
Aspects
Lombok or Eclipse Xtend
Code generators -> Spring Roo
JVM Languages
    Clojure
     Scala
    Groovy
     JRuby
    Jython
  Java Script
Clojure
- Lisp – WTF?
- By default Functional Programming only
Scala
- Syntax WTF
- Acclimatization period 6 to 12 months
JRuby
- Ruby guys
- gemns hell
Jython
- Python syntax ((
Java Script (Rhino)
- Is Java Script
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
Groovy Console
Primitives
3.times { println it }

assert (10 instanceof Integer)

println 4.4.class

String s = 10 as String;
println s;
Groovy Beans
class Customer {
   Integer id
   def name
   Date dob
}


def customer = new Customer(id:1, name:"Gromit",
dob:new Date())
Collections – Lists, Ranges
def list = [5, 6, 7, 8]
assert list[2] == 7
assert list instanceof java.util.List

def range = 5..8
assert range.size() == 4
assert range[2] == 7
assert range instanceof java.util.List
Collections - Map
def map = [name:"Gromit", likes:"cheese",
id:1234]
assert map["name"] == "Gromit"
assert map['id'] == 1234
assert map instanceof java.util.Map
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]
Duck typing
// Hey duck
Duck myDuck = new Duck()
myDuck.quack()

// Hey quacker
def duck = new Duck()
myDuck.quack()
Duck typing 2
class Duck {
   def quack() {println("quack")}
}

def action = "quack"
def duck = new Duck()
duck."${action}"()
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"
Closures
def squareClosure = { value ->
  value * value;
}

assert (4 == squareClosure(2))
IO
def file = new File(sms.txt).eachLine{ println it }

file.write(”rewrite file”)

file.append(“add to file”)
file << ”sexy style"
XML
def xml = new groovy.xml.MarkupBuilder()
xml.goods(type:”current”){
  good(“Beer”)
  good (“Rock&Roll”)
  good (“Girls”)
}
XML
def goods = new XmlSlurper().parseText(…)
def allGoods = records.name
assert 3 == allRecords.size()
def allNodes = goods.depthFirst().collect{ it }
def firstGood = goods.name[0]
assert ’sms’ == firstGood .name()
assert ‘Text’ == firstGood.@make.text()
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.&add
insert ”beer"
insert
  ”rock&roll"
Something to read
Groovy++
Grails -> GORM
Gradle
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);
At the end on Groovy
Safe navigation operator “?.”

infringementAction.setCustomsOffice(
versionedReplyInf?.getReplyInf()?.getInf()?.
getInf()?.getCustomsOffice())

Groovy vs Boilerplate and Ceremony Code

  • 1.
    JVM. quack() orGroovy vs Ceremony
  • 2.
  • 3.
    Java Language comeswith • Design Patterns • Boilerplate • Overly Ceremony code
  • 4.
  • 5.
  • 6.
    2. Boilerplate - getter/setters - Lazy init factories - toString, hashCode, equals - Explicit Exception declaration/handling - Close for resources - synchronization
  • 7.
  • 8.
    Code Today (DeathStar) ESSENCE CEREMONY
  • 9.
    Future: Paradigm, Languages, Frameworks CEREMONY ESSENCE
  • 10.
    3. Ceremony toEssence 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"); }
  • 11.
    Step 1. DuckTyping 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"); }
  • 12.
    Step 2. ducktyping, 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"); }
  • 13.
    Step 3. Implicitreturn, 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"); }
  • 14.
    Step 4. Don'tadd 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"); }
  • 15.
    Step 5. Conditionalsmake code expensive to test edit(mapping, form, request, response) { person = Person.find(form.getId()); form = convert(person); updateFormBean(mapping, request, form); mapping.findForward("edit"); }
  • 16.
    Step 6. Allaction methods have the same four arguments edit() { person = Person.find(form.getId()); form = convert(person); updateFormBean(mapping, request, form); mapping.findForward("edit"); }
  • 17.
    Step 7. Delegateobject showing to form edit() { person = Person.find(form.getId()); mapping.findForward("edit"); }
  • 18.
    Step 8. Standardrouting edit() { person = Person.find(form.getId()); } Or Ruby def edit @person = Person.find(params[:id]) end
  • 19.
    Java Word IoC Aspects Lombok orEclipse Xtend Code generators -> Spring Roo
  • 20.
    JVM Languages Clojure Scala Groovy JRuby Jython Java Script
  • 21.
    Clojure - Lisp –WTF? - By default Functional Programming only
  • 22.
    Scala - Syntax WTF -Acclimatization period 6 to 12 months
  • 23.
  • 24.
  • 25.
    Java Script (Rhino) -Is Java Script
  • 26.
    Starting Groovy 1. Downloadthe .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
  • 27.
  • 28.
    Primitives 3.times { printlnit } assert (10 instanceof Integer) println 4.4.class String s = 10 as String; println s;
  • 29.
    Groovy Beans class Customer{ Integer id def name Date dob } def customer = new Customer(id:1, name:"Gromit", dob:new Date())
  • 30.
    Collections – Lists,Ranges def list = [5, 6, 7, 8] assert list[2] == 7 assert list instanceof java.util.List def range = 5..8 assert range.size() == 4 assert range[2] == 7 assert range instanceof java.util.List
  • 31.
    Collections - Map defmap = [name:"Gromit", likes:"cheese", id:1234] assert map["name"] == "Gromit" assert map['id'] == 1234 assert map instanceof java.util.Map
  • 32.
    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]
  • 33.
    Duck typing // Heyduck Duck myDuck = new Duck()
myDuck.quack() // Hey quacker def duck = new Duck()
myDuck.quack()
  • 34.
    Duck typing 2 classDuck { def quack() {println("quack")} } def action = "quack" def duck = new Duck() duck."${action}"()
  • 35.
    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"
  • 36.
    Closures def squareClosure ={ value -> value * value; } assert (4 == squareClosure(2))
  • 37.
    IO def file =new File(sms.txt).eachLine{ println it } file.write(”rewrite file”) file.append(“add to file”)
file << ”sexy style"
  • 38.
    XML def xml =new groovy.xml.MarkupBuilder() xml.goods(type:”current”){ good(“Beer”) good (“Rock&Roll”) good (“Girls”) }
  • 39.
    XML def goods =new XmlSlurper().parseText(…) def allGoods = records.name assert 3 == allRecords.size() def allNodes = goods.depthFirst().collect{ it } def firstGood = goods.name[0] assert ’sms’ == firstGood .name() assert ‘Text’ == firstGood.@make.text()
  • 40.
    DSL This is areally 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.&add
insert ”beer"
insert ”rock&roll"
  • 41.
  • 42.
    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);
  • 43.
    At the endon Groovy Safe navigation operator “?.” infringementAction.setCustomsOffice( versionedReplyInf?.getReplyInf()?.getInf()?. getInf()?.getCustomsOffice())