Groovy – Simplify the life of (Java) developers – Über Groovy



Groovy – Simplify the life of (Java) developers – Über Groovy

0 0


hello-groovy

Introduction to Groovy

On Github dmies / hello-groovy

Groovy

Simplify the life of (Java) developers

von Daniel Mies

Agenda

  • Über Groovy
  • von Java zu Groovy
  • Closures
  • Collections und Strings
  • Traits

Über Groovy

Groovy

  • Programmier- und Skriptsprache auf der JVM
  • entwickelt von Pivotal (Spring Framework)
  • unterstützt dynamische und statische Typisierung
  • meist nahtlose Interoperabilität mit Java

Weit verbreitet...

Von Java zu Groovy

Java Code

public class Greeter {
   private String owner;

   public String getOwner() { return owner; }

   public void setOwner(String owner) { this.owner = owner; }

   public String greet(String name) {
      return "Hello " + name + ", I'm " + owner;
   }

   public static void main(String... args){
      Greeter greeter = new Greeter();
      greeter.setOwner("Max");
      System.out.println(greeter.greet("Moritz"));
   }
}

Groovy Code

public class Greeter {
   private String owner;

   public String getOwner() { return owner; }

   public void setOwner(String owner) { this.owner = owner; }

   public String greet(String name) {
      return "Hello " + name + ", I'm " + owner;
   }

   public static void main(String... args){
      Greeter greeter = new Greeter();
      greeter.setOwner("Max");
      System.out.println(greeter.greet("Moritz"));
   }
}

Default imports

import java.lang.*
import java.util.*
import java.net.*
import java.io.*
import java.math.BigInteger
import java.math.BigDecimal
import groovy.lang.*
import groovy.util.*
					

Optional in Groovy

In Groovy können einige Dinge weggelassen werden:

  • public keyword
  • Semikolon
  • return keyword
  • Klammern
  • Typen

Groovy Code

class Greeter {
   private String owner

   String getOwner() { owner }

   void setOwner(String owner) { this.owner = owner }

   String greet(String name) {
      "Hello " + name + ", I'm " + owner
   }

   static void main(String... args){
      def greeter = new Greeter()
      greeter.setOwner("Max")
      System.out.println greeter.greet("Moritz")
   }
}
				

Nützliche Eigenschaften

  • Properties ersetzen Getter/Setter
  • Property Notation
  • named constructors
  • GStrings
  • Nutzung als Skriptsprache

Groovy Code

class Greeter {
   String owner

   String greet(String name) { "Hello ${name}, I'm ${owner}" }
}

def greeter = new Greeter(owner: "Max")
// greeter.owner = "Max"
// greeter["owner"] = "Max"
println greeter.greet("Moritz")
			

Mehr Groovy

  • Closures
    def adder = {a,b -> a+b}
  • Listen
    def list = [1, 2, 3]
  • Maps
    def map = [a:1, b:2, c:3]
  • Reguläre Ausdrücke
    def regex = ~/.*foo.*/
  • Ranges
    def range = 'a'..'z'

Closures

Closures: Grundlagen

def adder = {a,b -> a+b}
// Closure adder = ...

assert adder.call(1,2) == 3
assert adder('a','b') == 'ab'
			

Closures: Implizite Parameter

def doubler = {it * 2}

assert doubler(2) == 4
			

Closures: Variable Parameter

def sum = {... elements -> elements.sum()}

assert sum(1, 2, 3) == 6
assert sum('c', 'g', 'm') == 'cgm'
			

Closures: Standardwerte

def intAdder = {int a, int b = 4 -> a + b}

assert intAdder(1, 2) == 3
assert intAdder(1) == 5
			

Closures: Methoden als Closure verwenden

def printer = System.out.&println

printer "Hallo"
			

Closures: Beispiel

@groovy.transform.Immutable
class Person {
   String name
   Integer age
}

def persons = [
   new Person('Guillaume', 36),
   new Person('Marion', 5),
   new Person('Erine', 1)]

def names = persons.findAll { it.age < 18 }
                   .collect { it.name.toUpperCase() }
                   .sort()
                   .join(', ')

assert names == 'ERINE, MARION'

Closures: Eigene Kontrollstrukturen

void ifNot(boolean cond, Closure c) { if (!cond) c() }
def printer = System.out.&println

ifNot(10 < 9) {
   printer "10 is not < 9"
}

// ifNot((10 < 9){...})
			

Collections und Strings

Listen

def list = ['a', 'b', 'c']
list << 'd'
assert list.contains('d')
assert list.findAll { it.startsWith 'a' }.size() == 1
assert list.collect { it.toUpperCase() }
== ['A', 'B', 'C', 'D']
assert list.inject('') { a, b -> a + b } == 'abcd'
			

Maps

def map = [name: 'Guillaume', age: 36]
map.daughters = ['Marion', 'Erine']
assert map['daughters'].contains('Marion')
			

Ranges

def range = 'a'..'z'

assert range.contains('m')
assert range.contains('z')

def exclusive = 1..<10

assert !exclusive.contains(10)
def reverse = 10..0

assert reverse[0] == 10
assert reverse[-1] == 0
			

Strings, GStrings, Multiline Strings

def name = 'Groovy'
def tmpl = """
Dear Mr ${name},
You're the winner of the lottery!
Yours sincerly,
"""
assert tmpl.toString().contains('Groovy')
			

Traits

Eigenschaften

  • wie Interfaces aber mit Methoden
  • stateful (mit Properties)
  • Voll kompatibel zu Java
  • können auch zur Laufzeit verwendet werden

Beispiel

trait FlyingAbility{
   String fly(){ "I'm flying" }
}

class Bird implements FlyingAbility{}

def bird = new Bird()

assert bird.fly() == "I'm flying"
		

Properties

trait Named{
   String name
}

class Bird implements Named{}

def bird = new Bird(name: "Colibri")

assert bird.name == "Colibri"
	

Vererbung

trait Named{
   String name
}

trait FlyingAbility extends Named{
   String fly(){ "I'm a flying ${name}" }
}

class Bird implements FlyingAbility{}

def bird = new Bird(name: "Colibri")

assert bird.name == "Colibri"
assert bird.fly() == "I'm a flying Colibri"

Mehrfachvererbung

trait Named{
   String name
}

trait FlyingAbility{
   String fly(){ "I'm a flying ${name}" }
}

class Bird implements FlyingAbility, Named{}

def bird = new Bird(name: "Colibri")

assert bird.name == "Colibri"
assert bird.fly() == "I'm a flying Colibri"

Mehrfachvererbung: Konflikte

trait KiteSurfer{
   String surf() { "kite" }
}

trait WebSurfer{
   String surf() { "web" }
}

class Hipster implements KiteSurfer, WebSurfer{}

def hipster = new Hipster()

assert hipster.surf() == "web"

Mehrfachvererbung: Konflikte (2)

trait KiteSurfer{
   String surf() { "kite" }
}

trait WebSurfer{
   String surf() { "web" }
}

class Hipster implements KiteSurfer, WebSurfer{
   String surf() { KiteSurfer.super.surf() }
}

def hipster = new Hipster()

assert hipster.surf() == "kite"

Verwendung @ Runtime

trait Named{
   String name
}

class Animal{}

def bird = new Animal() as Named
bird.name = "Colibri"

assert bird.name == "Colibri"

Verwendung @ Runtime (2)

trait Named{
   String name
}

trait Quacks{
   String quack() { "quack" }
}

class Animal{}

def bird = new Animal().withTraits Named, Quacks
bird.name = "Donald"

assert bird.name == "Donald"
assert bird.quack() == "quack"

Traits...

  • können private Felder und Methoden haben
  • können abstrakte Methoden haben
  • Interfaces implementieren
  • von mehreren Traits erben oder diese implementieren

Fragen?

Vielen Dank für Eure Aufmerksamkeit.