Mehr Dynamik Durch Skriptsprachen

jlink
Mehr Dynamik bei der
Softwareentwicklung
 Skriptsprachen im Vergleich
Wer ich bin...
    Mein eigener Chef

    (Extremer) Softwareentwickler

    (Agiler) Coach

    Testgetrieben

    http://johanneslink.net
Java-Frust
public class Person...
    public String getName() {
          return name;
    }


public static List<Person> sortByName(Set<Person> people) {
    List<Person> sortedResult = new ArrayList<Person>(people);
    Comparator<Person> nameComparator = new Comparator<Person>() {
        public int compare(Person o1, Person o2) {
            return o1.getName().compareTo(o2.getName());
        }
    };
    Collections.sort(sortedResult, nameComparator);
    return sortedResult;
}


public class FinancialInstrument...
    public String getName() {
          return name;
    }
Java-Frust
  public class Person implements Namable...
      public String getName() {
            return name;
      }

public class MyHelper...
  public static List<Person> Namable> List<T> sortByName(Set<T> namables) {
    public static <T extends sortByName(Set<Person> people) {
    
 List<Person> sortedResult = ArrayList<T>(namables);
       List<T> sortedResult = new new ArrayList<Person>(people);
    
 Comparator<Person> nameComparator = Comparator<T>() {
       Comparator<T> nameComparator = new new Comparator<Person>() {
    
 
    public int compare(Person T o2) {
           public int compare(T o1, o1, Person o2) {
    
 
    
   return o1.getName().compareTo(o2.getName());
               return o1.getName().compareTo(o2.getName());
    
 
    }
           }
    
 };
       };
      Collections.sort(sortedResult, nameComparator);
    
 Collections.sort(sortedResult, nameComparator);
    
 return sortedResult;
       return sortedResult;
  } }


  public class FinancialInstrument implements Namable...
      public String getName() {
            return name;
      }
Java-Frust
  public class Person...
      public String getName() {
            return name;
      }

public class MyHelper...
    public static <T extends Namable> List<T> sortByName(Set<T> namables) {
    
 List<T> sortedResult = new ArrayList<T>(namables);
    
 Comparator<T> nameComparator = new Comparator<T>() {
    
 
    public int compare(T o1, T o2) {
    Collection sortByName
    
 
    
   return o1.getName().compareTo(o2.getName());

     self sort: [:each | each name]
    
 
    
 };
           }

    
 Collections.sort(sortedResult, nameComparator);
    
 return sortedResult;
    }


  public class FinancialInstrument...
      public String getName() {
            return name;
      }
Typische Java Smells
public class MyHelper...
    public static <T extends Namable> List<T> sortByName(Set<T> namables) {
    
 List<T> sortedResult = new ArrayList<T>(namables);
    
 Comparator<T> nameComparator = new Comparator<T>() {
    
 
    public int compare(T o1, T o2) {
    
 
    
   return o1.getName().compareTo(o2.getName());
    
 
    }
    
 };
    
 Collections.sort(sortedResult, nameComparator);
    
 return sortedResult;
    }




    • Variables Verhalten erfordert eigene (anonyme) Klasse
    • Incomplete Library Smell
    • Statische Typisierung erzwingt viele gemeinsame
       Interfaces
    • Unvorhergesehene Veränderung => Neukompilierung
Die Rettung naht:
Dynamische Skriptsprachen



• Scripting
• Dynamik
Scripting
 • Knappe und ausdrucksstarke Syntax
 • Ausführung von Programmcode ohne
   (spürbare) Compilierung
   • Selbstständige Skripte
   • Aus einer Applikation heraus
List<Person> people = new ArrayList<Person>();
people.add(new Person(quot;Dierkquot;));
...
List<Person> sorted = (List<Person>) Eval.x(people,
    quot;x.sort {it.name}quot;
);
Dynamik


• Dynamische Typisierung
• Closures
• Meta-Programmierung
Dynamische Typisierung
       aka „Duck Typing“
def sortByName(unsorted) {
    unsorted.sort {it.name}
}

def people = [
    new Student(quot;Johannesquot;),
    new Person(quot;Dierkquot;)
]
def sorted = sortByName(people)
assert sorted[0].name == quot;Dierkquot;
assert sorted[1].name == quot;Johannesquot;
Closures (1)

 Programmlogik als vollwertiges Objekt

def sorter = { unsorted ->
    unsorted.sort {it.name}
}
def sorted = sorter(people)

//oder so:
def sorted = sorter.call(people)
Closures (2)

    • Iteration als typischer Anwendungsfall
def namen = [quot;Johannesquot;, quot;Frankquot;, quot;Dierkquot;]
def auswahl = namen.findAll {name -> name.contains quot;nquot;}
assert auswahl == [quot;Johannesquot;, quot;Frankquot;]


List<String> auswahl = new ArrayList<String>();
for (String name : namen) {

    if (name.contains(quot;nquot;)) {

    
 auswahl.add(name);

    }
}
                            Äquivalenter Java Code
Meta-Programmierung


• Erweiterung existierender Klassen
• Hinzufügen von Methoden zur Laufzeit
• Erweiterung / Veränderung der
  Sprache durch Eingriff Verwendung
  eines „Meta Object Protocol“
Meta Object Protocol
  „A metaobject protocol (MOP) is an interpreter
  of the semantics of a program that is open and
             extensible“ (Wikipedia)
Class.metaClass.'static'.create = { Object[] args ->
 class MyObject {
 
     def prop
  delegate.metaClass.invokeConstructor(*args)
}
     void setProperty(String name, value) {
 
     
 prop = value
assert }new ArrayList()
 
                           == ArrayList.create()
 
     def getProperty(String name) {
assert new HashMap()         == HashMap.create()
 
     
 prop
assert new Integer(42)       == Integer.create(42)
 
     }
assert new Dimension(1,1)    == Dimension.create(1,1)
 }
 def obj = new MyObject()
 obj.firstName = quot;Johannesquot;
 obj.lastName = quot;Linkquot;
 assert obj.firstName == quot;Linkquot;
Vorteile / Nachteile
dynamischer Skriptsprachen
• Vorteile:
  • Weniger Code
  • Weniger Duplikation
  • Verständlichere Abstraktionen
  • Mehr Deployment-Optionen
• Nachteile:
  • Erschwerte statische Codeanalyse
  • Schlechtere Performance
Welche Skriptsprachen
       gibt es?
• Verbreiteste Skriptsprachen:
  Perl, PHP, Python, Ruby, JavaScript

• Mehr als 200 verschiedene Sprachen
  allein auf der Java VM:
  Groovy, JRuby, Scala, Bistro ...

• Heute im Visier:
  JavaScript, Ruby und Groovy
Groovy
• Volle Objekt-         • Volle Integration
  Orientierung ohne       mit der Java-
  primitive Typen         Plattform
• Optionale statische     • Generics
  Typisierung
                          • Annotations
• Closures                • Security-Model
• Listen und Maps       • Wird (immer) in
  als Literale
                          echten Bytecode
                          kompiliert
Groovy - Vereinfachte
          Syntax
 System.out.println(quot;Hello World!quot;); //Java style
 println 'Hello, World!'
 def vorname = 'Stefan'
 println quot;$vorname, ich hol' den Wagen.quot;
 String lang = quot;quot;quot;Du, ${vorname}, der
 Wagen steht eine Zeile weiter.quot;quot;quot;
 assert 0.5 == 1/2


class Person {

 def name
}
def johannes = new Person(name: quot;Johannesquot;)
assert johannes.name == quot;Johannesquot;
Groovy -Closures
def to = quot;JUGSquot;
def say = { msg ->
    msg + quot;, $toquot;
}
assert say(quot;Halloquot;) == quot;Hallo, JUGSquot;
to = quot;JUG Colognequot;
assert say(quot;Halloquot;) == quot;Hallo, JUG Colognequot;

(1..10).each {
    println it
}
[a:1, b:2].each { key, value ->

    println quot;key: $key, value: $valuequot;
}
JavaScript
• Objektorientiert - aber nicht klassenbasiert
• Keine statische Typisierung
• Syntax und ein paar Basis-Objekte an Java
    angelehnt
•   Läuft (interpretiert) in jedem Browser - im
    Detail unterschiedlich
•   Enge Verknüpfung mit DOM
•   Rhino-JS-Engine in Java SE 6 enthalten
•   Standardisiert als ECMAScript
JavaScript - Basistypen
var name = 'Johannes';
assertEqual('Johannes Link', name + ' Link');
    
var eins = 1
assertEqual(2, eins + 1)
assertEqual('11', eins + '1')
   
var liste = [1, 2, 'drei']
assertEqual('drei', liste[2])
   
var isBig = eins > 1000
if (isBig) fail()
JavaScript - Objekte
    var johannes = new Object();
    johannes.firstName = quot;Johannesquot;
    johannes.lastName = quot;Linkquot;
    johannes.name = function() {
            return this.firstName + ' ' + this.lastName
    }
    assertEqual('Johannes Link', johannes.name());


var johannes = {

 firstName: 'Johannes', lastName: 'Link',

       name: function() {

       
 return this.firstName + ' ' + this.lastName

       }
}
JavaScript - Prototypen (1)
 function Person(firstName, lastName) {
     this.firstName = firstName
     this.lastName = lastName
 }


 Person.prototype.name = function() {
 
   return this.firstName + ' ' + this.lastName
 }


 var johannes = new Person('Johannes', 'Link')
 assertEqual('Johannes Link', johannes.name())
 assertEqual(true, johannes instanceof Person)
JavaScript - Prototypen (2)
  johannes.name = function() {
  
    return 'Joe Cartwright'
  }
  assertEqual('Joe Cartwright', johannes.name())


 function Student(firstName, lastName) {
 
 Person.call(this, firstName, lastName);
 }
 Student.prototype = new Person();
 Student.prototype.name = function() {
 
 return this.firstName;
 }
 var jannek = new Student('Jannek', 'Link');
 assertEqual('Jannek', jannek.name());
 assertEqual('Link', jannek.lastName);
Ruby
• Sprachumfang und Mächtigkeit
  ähnlich wie bei Groovy

• C-Implementierung als Interpreter
• „Berühmt“ durch Ruby on Rails
• Ausschließlich dynamische Typen
• JRuby: Byte-Code und Java-
  Integration
Ruby - Code
class Person
  attr_reader :first_name, :last_name
  def initialize(first_name, last_name)
    @first_name = first_name
    @last_name = last_name
  end
end
class Person
  def name()
    first_name + quot; quot; + last_name
  end
end
johannes = Person.new(quot;Johannesquot;, quot;Linkquot;)
assert_equal quot;Johannes Linkquot;, johannes.name
Ruby - Blocks
 def three_times(arg)
   yield arg
   yield arg
   yield arg
 end
 three_times (quot;JUGSquot;) { |name| puts quot;Hello, quot; + name }


def twice(arg, action)
  action.call(arg)
  action.call(arg)
end
print_ciao = proc { |name| puts quot;Ciao, quot; + name }
twice quot;JUGSquot;, print_ciao
Ruby - Mixins
 module Debug
   def who_am_i
     quot;#{self.class.name}quot;
   end
 end

 class Person
   include Debug
 end
 johannes = Person.new(quot;Johannesquot;, quot;Linkquot;)
 assert_equal quot;Personquot;, johannes.who_am_i


s = quot;Ein Stringquot;
class Array
s.extend Debug
  include Debug
assert_equal quot;Stringquot;, s.who_am_i
end
assert_equal quot;Arrayquot;, [1, 2, 3].who_am_i
Ruby Classes are Objects
 johannes = Person.new(quot;Johannesquot;, quot;Linkquot;)
 assert_equal Person, johannes.class
 assert_equal Class, Person.class
 assert_equal Class, Class.class
 assert_equal Module, Class.superclass
 assert_equal Object, Module.superclass


class Class
  alias_method :old_new, :new
  def new(*args)
    puts quot;Objekt wird erzeugt...quot;
    old_new(*args)
  end
end
Ruby Events

    Event                  Hook
  Methodenaufruf         Kernel::system


Methode hinzufügen     Module#method_added

Unterklasse erzeugen     Class#inherited


         ...
Vergleich (1)
                  Groovy            JavaScript        Ruby / JRuby
               gering, deutlich          groß,
Verbreitung                                           mittel, wachsend
                  wachsend          gleichbleibend
                                   wenig eingebaut,
Bibliotheken     J2EE + GDK                           zahlreich /+J2EE
                                   viele externe Libs
                 dynamisch,
Typisierung                           dynamisch         dynamisch
               optional statisch
Objektorien-                          Objekte +
                 vollständig                            vollständig
  tierung                          primitive Typen

 Vererbung      klassenbasiert     Prototyp-basiert    klassenbasiert

                sehr mächtig
   MOP                                  gering        sehr mächtig++
                  (ab 1.5)
Vergleich (2)
                       Groovy         JavaScript      Ruby / JRuby

                                                         gut, aber mit
Java-Integration       optimal           gering
                                                      prinzp. Problemen
    Laufzeit-        kompilierter                      interpretiert /
                                      interpretiert
   umgebung        Bytecode auf JVM                    JVM Bytecode
     Tool-           mäßig bis gut
                                         mäßig          mäßig bis gut
 Unterstützung         (IDEA)
  Typisches    Scripting in Java-
                                  Ajax im Browser       Ruby on Rails
Anwendungsfeld  Applikationen

                   langsam, besser
 Performance                            langsam       meist ausreichend
                      werdend

http://shootout.alioth.debian.org/
Strack Trace Java
Thread [main] (Suspended (breakpoint at line 22 in JavaPerson))	

	

  JavaPerson.doubleName() line: 22	

	

  JavaTester.run() line: 7	

	

  Tester.test(Class<Runnable>) line: 16	

	

  Tester.main(String[]) line: 6
Stack Trace Groovy
Thread [main] (Suspended (breakpoint at line 18 in GroovyPerson))	

	

     GroovyPerson.doubleName() line: 18	

	

     NativeMethodAccessorImpl.invoke0(Method, Object, Object[])
	

     NativeMethodAccessorImpl.invoke(Object, Object[]) line: 39	

	

     DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 25	

	

     Method.invoke(Object, Object...) line: 585	

	

     CachedMethod.invoke(Object, Object[]) line: 95	

	

     MetaClassHelper.doMethodInvoke(Object, MetaMethod, Object[]) line: 599	

	

     MetaClassImpl.invokeMethod(Class, Object, String, Object[], boolean, boolean) line: 904	

	

     MetaClassImpl.invokeMethod(Object, String, Object[]) line: 740	

	

     InvokerHelper.invokePogoMethod(Object, String, Object) line: 773	

	

     InvokerHelper.invokeMethod(Object, String, Object) line: 753	

	

     ScriptBytecodeAdapter.invokeMethodN(Class, Object, String, Object[]) line: 167	

	

     ScriptBytecodeAdapter.invokeMethod0(Class, Object, String) line: 195	

	

     GroovyTester.run() line: 7	

	

     Tester.test(Class<Runnable>) line: 16	

	

     Tester.main(String[]) line: 7
Warum gerade jetzt?
• Normale Pendelschwingung zwischen
    dynamischer und statischer Typisierung
•   Frust über Redundanz und wachsende
    Komplexität von Java
•   Domänen-spezifische Sprachen sind auf
    dem Vormarsch
•   Multi-Sprachen-Systeme werden hoffähig
•   Mehr Wissen über sinnvolle
    Einsatzszenarien der unterschiedlichen
    Programmiersprachen
Einsatzmuster für Scripting
    (von Dierk König)
• Alleskleber
• Weiches Herz
• Kluge Anpassung
• Endoskopische Operation
• Grenzenlose Offenheit
• Heinzelmännchen
• Prototyp
Einsatzmuster:
         Alleskleber
• Applikationen aus bestehenden
  Komponenten zusammenbauen

• Java und .NET sind gut geeignet für
  stabile Infrastruktur: Middleware,
  Frameworks, Widget Sets, Services

• Scripting ist gut geeignet für flexible
  View- und Controller-Schichten (z.B.
  Grails)
Alleskleber Demo:
       RSS Reader


• Zusammenbau von XML Parser, Java
 Networking und Swing Widget
 Bibliothek, um einen Standard-RSS
 Feed darzustellen
Einsatzmuster:
        Weiches Herz
• Fachliche Modelle auslagern bei
  vorgegebenem Java-Applikationsgerüst

• Fachlichen Erkenntnisfortschritt
  ermöglichen: Entitäten, Beziehungen
  und Verhalten bleiben durch Scripting
  flexibel

• Verhaltensänderung zur Laufzeit
Weiches Herz Beispiel:
   Bonusberechnung
umsatz = mitarbeiter.umsatz
switch(umsatz / 1000) {
    case 0..100: return umsatz * 0.04
    case 100..200: return umsatz * 0.05
    case {it > 200}:
       bonusClub.add(mitarbeiter)
       return umsatz * 0.06
}

Binding binding = new Binding();
binding.setVariable(quot;mitarbeiterquot;, mitarbeiter);
binding.setVariable(quot;bonusClubquot;, bonusClub);
GroovyShell shell = new GroovyShell(binding);
File script = new File(filename);
BigDecimal bonus = (BigDecimal) shell.evaluate(script);
Einsatzmuster:
     Kluge Anpassung
• Konfigurationen mit Ausführungs-Logik als
  Ersatz für XML-Konfigurationen
  • Mit Referenzen, Schleifen, Bedingungen,
    Vererbung, Ausführungslogik,
    Umgebungsermittlung, ...
• Typischer Anwendungsfall für domänen-
  spezifische Sprachen (DSLs)
• Veränderungen durch den Experten
DSL-Beispiel (Bernd Schiffer):
   Entfernungsberechnung
assert 5001.m == 2000.m + 3.km + 1.m

class Distance {
  def meter
assert werteAus('5002 m == 2000 m + 3           km + 2 m')
  def plus(other) {
     new Distance(meter: meter + other.meter)
def werteAus(String ausdruck) {
  }
  boolean equals(other) {
  Eval.me(
     this.meter == other.meter
  } ausdruck.replaceAll(quot; (m|km)quot;, {
}       alle, einheit -> quot;.${einheit}quot;
  }))
class DistanceCategory {
} static def getM(distance) {
     new Distance(meter: distance)
  }
  static def getKm(distance) {
     new Distance(meter: distance * 1000)
  }
}
Einsatzmuster:
Endoskopische Operation
• Minimal-invasive Eingriffe quot;in vivoquot;
• Viele Notwendigkeiten für Anpassungen
  ad-hoc Anfragen sind nicht vorhersehbar

• Schlüsselloch für die Live Ausführung von
  Scripts schaffen, z.B. in einem speziellen
  Servlet

• Unglaublich wertvoll für Produkt-Support,
  Fehleranalyse, Hot-Fixes, Notfälle
Endoskopische
    Operation: im Servlet
Probleme mit der Datenbank Verbindung?
def ds = Config.dataSource
ds.connection = new DebugConnection(ds.connection)




Gefährliche Benutzer rauswerfen
users = servletContext.getAttribute('users')
bad = users.findAll { user ->
       user.cart.items.any { it.price < 0 }
}
servletContext.setAttribute('users', users - bad)
Einsatzmuster:
 Grenzenlose Offenheit
• Jede Zeile Code wird änderbar
• Manchmal sind die vorgesehenen
  Variationspunkte nicht ausreichend

• Einfache Änderungen ohne
  langwieriges Setup für Kompilation
  und Deployment

• Perl, PHP, Python, etc. machen es vor
Einsatzmuster:
    Heinzelmännchen
• Repetitive Aufgaben automatisieren
• Automatisierter Build, kontinuierliche
  Integration, Deployment,
  Installationen, Server-Überwachung,
  Reports, Statistiken, Erzeugen von
  Dokumentation, funktionale Tests
  uvm.

• Anwendungen mit Ant, Maven und Co.
Heinzelmännchen:
        Mail schicken
def users = [ [name:'Johannes', email:'jux@johanneslink.net'],
              [name:'Teilnehmer', email:'wer@wo.net']]

def ant = new groovy.util.AntBuilder()
for (user in users) {
ant.mail(mailhost: 'smtp.googlemail.com', mailport: '465',
    ssl: 'true', user: quot;$mailUserquot;, password: quot;$passwordquot;,
    subject: 'Vortrag ist bald fertig') {
  from(address: 'johannes.link@googlemail.com')
  to(address: user.email)
  message( quot;quot;quot;
      Hallo ${user.name},
      Der Vortrag ist fast fertig:
      ${new Date().toGMTString()} quot;quot;quot; )
}   }
Einsatzmuster: Prototyp
• Machbarkeitsstudien auf der
  Zielplattform

• quot;Spikesquot; für technologische oder
  algorithmische Ideen mit besserer
  Ausdrucksmächtigkeit, schnellerem
  Feedback und besseren
  Analysemöglichkeiten

• Wahlmöglichkeit für spätere (Teil-)
  Portierung nach Java / C#
Weitere Informationen
• Groovy:
  • http://groovy.codehaus.org/
  • Dierk König et al: „Groovy in Action“
• JavaScript:
  • http://developer.mozilla.org/en/docs/JavaScript
  • David Flanagan: „JavaScript: The Definitive Guide“
  • Microsoft: „ JScript Deviations from ES3“
• Ruby:
  • http://www.ruby-lang.org
  • Dave Thomas et al.: „Programming Ruby: The
     Pragmatic Programmers' Guide“
• http://www.nealford.com/downloads/conferences/
  Neal_Ford-Comparing_Groovy_and_JRuby-slides.pdf
Zusammenfassung

• Java - und andere Entreprise-Plattformen -
  haben Einschränkungen:
  • Anpassungen zur Laufzeit
  • Präzision im Ausdruck
  • Erweiterbarkeit der Sprache
• Dynamische Skriptsprachen sind in diesen
  Punkten flexibler und mächtiger
  • bringen jedoch andere Probleme mit sich
• Nicht statisch vs dynamisch, sondern...
Zeremonie
  versus
 Essenz
1 of 51

Recommended

Einführung in die funktionale Programmierung by
Einführung in die funktionale ProgrammierungEinführung in die funktionale Programmierung
Einführung in die funktionale ProgrammierungDigicomp Academy AG
1.8K views85 slides
Java Script Ist Anders by
Java Script Ist AndersJava Script Ist Anders
Java Script Ist Andersjlink
976 views24 slides
T3ak12 extbase by
T3ak12 extbaseT3ak12 extbase
T3ak12 extbasee-net Consulting GmbH & Co. KG
1.7K views15 slides
JdbcTemplate aus Spring by
JdbcTemplate aus SpringJdbcTemplate aus Spring
JdbcTemplate aus Springtutego
1.7K views36 slides
Genügend gute Gründe, wieso Ruby besser als PHP ist by
Genügend gute Gründe, wieso Ruby besser als PHP istGenügend gute Gründe, wieso Ruby besser als PHP ist
Genügend gute Gründe, wieso Ruby besser als PHP istDaniel Spangenberg
1.5K views14 slides
Prototype 1.7 by
Prototype 1.7Prototype 1.7
Prototype 1.7msebel
331 views98 slides

More Related Content

What's hot

Praesentation TYPO3Camp Berlin Speed mit Extbase by
Praesentation TYPO3Camp Berlin Speed mit ExtbasePraesentation TYPO3Camp Berlin Speed mit Extbase
Praesentation TYPO3Camp Berlin Speed mit ExtbaseStefan Frömken
1.4K views34 slides
P6kontext2014 by
P6kontext2014P6kontext2014
P6kontext2014lichtkind
666 views239 slides
Perl 5.20: Feature, Kultur, Module, Werkzeuge by
Perl 5.20: Feature, Kultur, Module, WerkzeugePerl 5.20: Feature, Kultur, Module, Werkzeuge
Perl 5.20: Feature, Kultur, Module, Werkzeugelichtkind
762 views195 slides
Perl 5 Quiz Chemnitz Edition by
Perl 5 Quiz Chemnitz EditionPerl 5 Quiz Chemnitz Edition
Perl 5 Quiz Chemnitz Editionlichtkind
1K views147 slides
L Sungs Vorschlag Seite15 by
L Sungs Vorschlag Seite15L Sungs Vorschlag Seite15
L Sungs Vorschlag Seite15Betablocker
97 views2 slides
Von Java Zu Groovy by
Von Java Zu GroovyVon Java Zu Groovy
Von Java Zu Groovyjlink
3.1K views66 slides

What's hot(20)

Praesentation TYPO3Camp Berlin Speed mit Extbase by Stefan Frömken
Praesentation TYPO3Camp Berlin Speed mit ExtbasePraesentation TYPO3Camp Berlin Speed mit Extbase
Praesentation TYPO3Camp Berlin Speed mit Extbase
Stefan Frömken1.4K views
P6kontext2014 by lichtkind
P6kontext2014P6kontext2014
P6kontext2014
lichtkind666 views
Perl 5.20: Feature, Kultur, Module, Werkzeuge by lichtkind
Perl 5.20: Feature, Kultur, Module, WerkzeugePerl 5.20: Feature, Kultur, Module, Werkzeuge
Perl 5.20: Feature, Kultur, Module, Werkzeuge
lichtkind762 views
Perl 5 Quiz Chemnitz Edition by lichtkind
Perl 5 Quiz Chemnitz EditionPerl 5 Quiz Chemnitz Edition
Perl 5 Quiz Chemnitz Edition
lichtkind1K views
L Sungs Vorschlag Seite15 by Betablocker
L Sungs Vorschlag Seite15L Sungs Vorschlag Seite15
L Sungs Vorschlag Seite15
Betablocker97 views
Von Java Zu Groovy by jlink
Von Java Zu GroovyVon Java Zu Groovy
Von Java Zu Groovy
jlink3.1K views
Guava - Google Core Libraries for Java 1.5+ by Johannes Degler
Guava - Google Core Libraries for Java 1.5+Guava - Google Core Libraries for Java 1.5+
Guava - Google Core Libraries for Java 1.5+
Johannes Degler1.1K views
Python crash-kurs by klausbremer
Python crash-kursPython crash-kurs
Python crash-kurs
klausbremer3.9K views
OpenLDAP - A developer's perspective by Gerrit Beine
OpenLDAP - A developer's perspectiveOpenLDAP - A developer's perspective
OpenLDAP - A developer's perspective
Gerrit Beine745 views
Drupal Entities by drubb
Drupal EntitiesDrupal Entities
Drupal Entities
drubb2.6K views
Battle of the Languages: Java und Python im Wettstreit beim Lösen von Program... by gedoplan
Battle of the Languages: Java und Python im Wettstreit beim Lösen von Program...Battle of the Languages: Java und Python im Wettstreit beim Lösen von Program...
Battle of the Languages: Java und Python im Wettstreit beim Lösen von Program...
gedoplan86 views
Java Persistence 2.0 by gedoplan
Java Persistence 2.0Java Persistence 2.0
Java Persistence 2.0
gedoplan383 views
2013-09-12, sfugcgn: CSS-Selektoren für Datenbankabfragen nutzen by Carsten Hetzel
2013-09-12, sfugcgn: CSS-Selektoren für Datenbankabfragen nutzen2013-09-12, sfugcgn: CSS-Selektoren für Datenbankabfragen nutzen
2013-09-12, sfugcgn: CSS-Selektoren für Datenbankabfragen nutzen
Carsten Hetzel808 views
AdvancedTdd by jlink
AdvancedTddAdvancedTdd
AdvancedTdd
jlink1.1K views

Viewers also liked

LibGuides and Evolving Learning Spaces by
LibGuides and Evolving Learning SpacesLibGuides and Evolving Learning Spaces
LibGuides and Evolving Learning SpacesKenneth Ronkowitz
1.3K views29 slides
Mehr Dynamik Mit Groovy by
Mehr Dynamik Mit GroovyMehr Dynamik Mit Groovy
Mehr Dynamik Mit Groovyjlink
1.1K views88 slides
Problem Based Learning - PBL, an introduction by
Problem Based Learning - PBL, an introductionProblem Based Learning - PBL, an introduction
Problem Based Learning - PBL, an introductionKenneth Ronkowitz
1.4K views24 slides
Mein paralleles Leben als Java-Entwickler by
Mein paralleles Leben als Java-EntwicklerMein paralleles Leben als Java-Entwickler
Mein paralleles Leben als Java-Entwicklerjlink
910 views158 slides
Ripple Effect: Faculty Redesign Through Course Redesign by
Ripple Effect: Faculty Redesign Through Course RedesignRipple Effect: Faculty Redesign Through Course Redesign
Ripple Effect: Faculty Redesign Through Course RedesignKenneth Ronkowitz
542 views28 slides
The Writing Initiative: Granted, Technology Makes Better Writers by
The Writing Initiative: Granted, Technology Makes Better WritersThe Writing Initiative: Granted, Technology Makes Better Writers
The Writing Initiative: Granted, Technology Makes Better WritersKenneth Ronkowitz
789 views28 slides

Viewers also liked(16)

LibGuides and Evolving Learning Spaces by Kenneth Ronkowitz
LibGuides and Evolving Learning SpacesLibGuides and Evolving Learning Spaces
LibGuides and Evolving Learning Spaces
Kenneth Ronkowitz1.3K views
Mehr Dynamik Mit Groovy by jlink
Mehr Dynamik Mit GroovyMehr Dynamik Mit Groovy
Mehr Dynamik Mit Groovy
jlink1.1K views
Problem Based Learning - PBL, an introduction by Kenneth Ronkowitz
Problem Based Learning - PBL, an introductionProblem Based Learning - PBL, an introduction
Problem Based Learning - PBL, an introduction
Kenneth Ronkowitz1.4K views
Mein paralleles Leben als Java-Entwickler by jlink
Mein paralleles Leben als Java-EntwicklerMein paralleles Leben als Java-Entwickler
Mein paralleles Leben als Java-Entwickler
jlink910 views
Ripple Effect: Faculty Redesign Through Course Redesign by Kenneth Ronkowitz
Ripple Effect: Faculty Redesign Through Course RedesignRipple Effect: Faculty Redesign Through Course Redesign
Ripple Effect: Faculty Redesign Through Course Redesign
Kenneth Ronkowitz542 views
The Writing Initiative: Granted, Technology Makes Better Writers by Kenneth Ronkowitz
The Writing Initiative: Granted, Technology Makes Better WritersThe Writing Initiative: Granted, Technology Makes Better Writers
The Writing Initiative: Granted, Technology Makes Better Writers
Kenneth Ronkowitz789 views
Agile08: Test Driven Ajax by jlink
Agile08: Test Driven AjaxAgile08: Test Driven Ajax
Agile08: Test Driven Ajax
jlink2.2K views
Blogging As Pedagogic Practice Across the Curriculum by Kenneth Ronkowitz
Blogging As Pedagogic Practice Across the CurriculumBlogging As Pedagogic Practice Across the Curriculum
Blogging As Pedagogic Practice Across the Curriculum
Kenneth Ronkowitz4.4K views
2013: The Beginning of the End of the University by Kenneth Ronkowitz
2013: The Beginning of the End of the University2013: The Beginning of the End of the University
2013: The Beginning of the End of the University
Kenneth Ronkowitz553 views
Rubrics: Transparent Assessment in Support of Learning by Kenneth Ronkowitz
Rubrics: Transparent Assessment in Support of LearningRubrics: Transparent Assessment in Support of Learning
Rubrics: Transparent Assessment in Support of Learning
Kenneth Ronkowitz8.1K views

Similar to Mehr Dynamik Durch Skriptsprachen

SOLID Prinzipien, Designgrundlagen objektorientierter Systeme by
SOLID Prinzipien, Designgrundlagen objektorientierter SystemeSOLID Prinzipien, Designgrundlagen objektorientierter Systeme
SOLID Prinzipien, Designgrundlagen objektorientierter SystemeMario Rodler
910 views78 slides
Pyparsing by
PyparsingPyparsing
PyparsingAndreas Schreiber
1.6K views22 slides
Webcon 2012 Mobile Development mit Sencha Touch by
Webcon 2012  Mobile Development mit Sencha TouchWebcon 2012  Mobile Development mit Sencha Touch
Webcon 2012 Mobile Development mit Sencha TouchThorsten Suckow-Homberg
790 views65 slides
PostgreSQL: Eigene Aggregate schreiben by
PostgreSQL: Eigene Aggregate schreibenPostgreSQL: Eigene Aggregate schreiben
PostgreSQL: Eigene Aggregate schreibenHans-Jürgen Schönig
1.2K views37 slides
TypeScript by
TypeScriptTypeScript
TypeScriptJens Siebert
957 views25 slides
Apache CouchDB at PHPUG Karlsruhe, Germany (Jan 27th 2009) by
Apache CouchDB at PHPUG Karlsruhe, Germany (Jan 27th 2009)Apache CouchDB at PHPUG Karlsruhe, Germany (Jan 27th 2009)
Apache CouchDB at PHPUG Karlsruhe, Germany (Jan 27th 2009)Nils Adermann
625 views23 slides

Similar to Mehr Dynamik Durch Skriptsprachen(20)

SOLID Prinzipien, Designgrundlagen objektorientierter Systeme by Mario Rodler
SOLID Prinzipien, Designgrundlagen objektorientierter SystemeSOLID Prinzipien, Designgrundlagen objektorientierter Systeme
SOLID Prinzipien, Designgrundlagen objektorientierter Systeme
Mario Rodler910 views
Apache CouchDB at PHPUG Karlsruhe, Germany (Jan 27th 2009) by Nils Adermann
Apache CouchDB at PHPUG Karlsruhe, Germany (Jan 27th 2009)Apache CouchDB at PHPUG Karlsruhe, Germany (Jan 27th 2009)
Apache CouchDB at PHPUG Karlsruhe, Germany (Jan 27th 2009)
Nils Adermann625 views
Vermisste Sprachfeatures in Java (german) by Sven Efftinge
Vermisste Sprachfeatures in Java (german)Vermisste Sprachfeatures in Java (german)
Vermisste Sprachfeatures in Java (german)
Sven Efftinge727 views
Go - Googles Sprache für skalierbare Systeme by Frank Müller
Go - Googles Sprache für skalierbare SystemeGo - Googles Sprache für skalierbare Systeme
Go - Googles Sprache für skalierbare Systeme
Frank Müller927 views
.NET Summit 2016 München: EcmaScript 2015+ with TypeScript by Manfred Steyer
.NET Summit 2016 München: EcmaScript 2015+ with TypeScript.NET Summit 2016 München: EcmaScript 2015+ with TypeScript
.NET Summit 2016 München: EcmaScript 2015+ with TypeScript
Manfred Steyer386 views
Modern angular 02_angular_mit_type_script by Manfred Steyer
Modern angular 02_angular_mit_type_scriptModern angular 02_angular_mit_type_script
Modern angular 02_angular_mit_type_script
Manfred Steyer401 views
Tech Talk: Groovy by mwie
Tech Talk: GroovyTech Talk: Groovy
Tech Talk: Groovy
mwie1K views
Einführung in Scala im Vergleich mit Java by Marcel Rehfeld
Einführung in Scala im Vergleich mit JavaEinführung in Scala im Vergleich mit Java
Einführung in Scala im Vergleich mit Java
Marcel Rehfeld3.3K views
Creasoft - Windows powershell by Creasoft AG
Creasoft - Windows powershellCreasoft - Windows powershell
Creasoft - Windows powershell
Creasoft AG1.7K views
Java Code Quality: Gute Software braucht guten Code - Regeln für verständlich... by GFU Cyrus AG
Java Code Quality: Gute Software braucht guten Code - Regeln für verständlich...Java Code Quality: Gute Software braucht guten Code - Regeln für verständlich...
Java Code Quality: Gute Software braucht guten Code - Regeln für verständlich...
GFU Cyrus AG3.2K views
Performance trotz Entity Framwork by André Krämer
Performance trotz Entity FramworkPerformance trotz Entity Framwork
Performance trotz Entity Framwork
André Krämer761 views
JsUnconf 2014 by emrox
JsUnconf 2014JsUnconf 2014
JsUnconf 2014
emrox2.2K views

Mehr Dynamik Durch Skriptsprachen

  • 1. Mehr Dynamik bei der Softwareentwicklung Skriptsprachen im Vergleich
  • 2. Wer ich bin... Mein eigener Chef (Extremer) Softwareentwickler (Agiler) Coach Testgetrieben http://johanneslink.net
  • 3. Java-Frust public class Person... public String getName() { return name; } public static List<Person> sortByName(Set<Person> people) { List<Person> sortedResult = new ArrayList<Person>(people); Comparator<Person> nameComparator = new Comparator<Person>() { public int compare(Person o1, Person o2) { return o1.getName().compareTo(o2.getName()); } }; Collections.sort(sortedResult, nameComparator); return sortedResult; } public class FinancialInstrument... public String getName() { return name; }
  • 4. Java-Frust public class Person implements Namable... public String getName() { return name; } public class MyHelper... public static List<Person> Namable> List<T> sortByName(Set<T> namables) { public static <T extends sortByName(Set<Person> people) { List<Person> sortedResult = ArrayList<T>(namables); List<T> sortedResult = new new ArrayList<Person>(people); Comparator<Person> nameComparator = Comparator<T>() { Comparator<T> nameComparator = new new Comparator<Person>() { public int compare(Person T o2) { public int compare(T o1, o1, Person o2) { return o1.getName().compareTo(o2.getName()); return o1.getName().compareTo(o2.getName()); } } }; }; Collections.sort(sortedResult, nameComparator); Collections.sort(sortedResult, nameComparator); return sortedResult; return sortedResult; } } public class FinancialInstrument implements Namable... public String getName() { return name; }
  • 5. Java-Frust public class Person... public String getName() { return name; } public class MyHelper... public static <T extends Namable> List<T> sortByName(Set<T> namables) { List<T> sortedResult = new ArrayList<T>(namables); Comparator<T> nameComparator = new Comparator<T>() { public int compare(T o1, T o2) { Collection sortByName return o1.getName().compareTo(o2.getName()); self sort: [:each | each name] }; } Collections.sort(sortedResult, nameComparator); return sortedResult; } public class FinancialInstrument... public String getName() { return name; }
  • 6. Typische Java Smells public class MyHelper... public static <T extends Namable> List<T> sortByName(Set<T> namables) { List<T> sortedResult = new ArrayList<T>(namables); Comparator<T> nameComparator = new Comparator<T>() { public int compare(T o1, T o2) { return o1.getName().compareTo(o2.getName()); } }; Collections.sort(sortedResult, nameComparator); return sortedResult; } • Variables Verhalten erfordert eigene (anonyme) Klasse • Incomplete Library Smell • Statische Typisierung erzwingt viele gemeinsame Interfaces • Unvorhergesehene Veränderung => Neukompilierung
  • 7. Die Rettung naht: Dynamische Skriptsprachen • Scripting • Dynamik
  • 8. Scripting • Knappe und ausdrucksstarke Syntax • Ausführung von Programmcode ohne (spürbare) Compilierung • Selbstständige Skripte • Aus einer Applikation heraus List<Person> people = new ArrayList<Person>(); people.add(new Person(quot;Dierkquot;)); ... List<Person> sorted = (List<Person>) Eval.x(people, quot;x.sort {it.name}quot; );
  • 9. Dynamik • Dynamische Typisierung • Closures • Meta-Programmierung
  • 10. Dynamische Typisierung aka „Duck Typing“ def sortByName(unsorted) { unsorted.sort {it.name} } def people = [ new Student(quot;Johannesquot;), new Person(quot;Dierkquot;) ] def sorted = sortByName(people) assert sorted[0].name == quot;Dierkquot; assert sorted[1].name == quot;Johannesquot;
  • 11. Closures (1) Programmlogik als vollwertiges Objekt def sorter = { unsorted -> unsorted.sort {it.name} } def sorted = sorter(people) //oder so: def sorted = sorter.call(people)
  • 12. Closures (2) • Iteration als typischer Anwendungsfall def namen = [quot;Johannesquot;, quot;Frankquot;, quot;Dierkquot;] def auswahl = namen.findAll {name -> name.contains quot;nquot;} assert auswahl == [quot;Johannesquot;, quot;Frankquot;] List<String> auswahl = new ArrayList<String>(); for (String name : namen) { if (name.contains(quot;nquot;)) { auswahl.add(name); } } Äquivalenter Java Code
  • 13. Meta-Programmierung • Erweiterung existierender Klassen • Hinzufügen von Methoden zur Laufzeit • Erweiterung / Veränderung der Sprache durch Eingriff Verwendung eines „Meta Object Protocol“
  • 14. Meta Object Protocol „A metaobject protocol (MOP) is an interpreter of the semantics of a program that is open and extensible“ (Wikipedia) Class.metaClass.'static'.create = { Object[] args -> class MyObject { def prop delegate.metaClass.invokeConstructor(*args) } void setProperty(String name, value) { prop = value assert }new ArrayList() == ArrayList.create() def getProperty(String name) { assert new HashMap() == HashMap.create() prop assert new Integer(42) == Integer.create(42) } assert new Dimension(1,1) == Dimension.create(1,1) } def obj = new MyObject() obj.firstName = quot;Johannesquot; obj.lastName = quot;Linkquot; assert obj.firstName == quot;Linkquot;
  • 15. Vorteile / Nachteile dynamischer Skriptsprachen • Vorteile: • Weniger Code • Weniger Duplikation • Verständlichere Abstraktionen • Mehr Deployment-Optionen • Nachteile: • Erschwerte statische Codeanalyse • Schlechtere Performance
  • 16. Welche Skriptsprachen gibt es? • Verbreiteste Skriptsprachen: Perl, PHP, Python, Ruby, JavaScript • Mehr als 200 verschiedene Sprachen allein auf der Java VM: Groovy, JRuby, Scala, Bistro ... • Heute im Visier: JavaScript, Ruby und Groovy
  • 17. Groovy • Volle Objekt- • Volle Integration Orientierung ohne mit der Java- primitive Typen Plattform • Optionale statische • Generics Typisierung • Annotations • Closures • Security-Model • Listen und Maps • Wird (immer) in als Literale echten Bytecode kompiliert
  • 18. Groovy - Vereinfachte Syntax System.out.println(quot;Hello World!quot;); //Java style println 'Hello, World!' def vorname = 'Stefan' println quot;$vorname, ich hol' den Wagen.quot; String lang = quot;quot;quot;Du, ${vorname}, der Wagen steht eine Zeile weiter.quot;quot;quot; assert 0.5 == 1/2 class Person { def name } def johannes = new Person(name: quot;Johannesquot;) assert johannes.name == quot;Johannesquot;
  • 19. Groovy -Closures def to = quot;JUGSquot; def say = { msg -> msg + quot;, $toquot; } assert say(quot;Halloquot;) == quot;Hallo, JUGSquot; to = quot;JUG Colognequot; assert say(quot;Halloquot;) == quot;Hallo, JUG Colognequot; (1..10).each { println it } [a:1, b:2].each { key, value -> println quot;key: $key, value: $valuequot; }
  • 20. JavaScript • Objektorientiert - aber nicht klassenbasiert • Keine statische Typisierung • Syntax und ein paar Basis-Objekte an Java angelehnt • Läuft (interpretiert) in jedem Browser - im Detail unterschiedlich • Enge Verknüpfung mit DOM • Rhino-JS-Engine in Java SE 6 enthalten • Standardisiert als ECMAScript
  • 21. JavaScript - Basistypen var name = 'Johannes'; assertEqual('Johannes Link', name + ' Link'); var eins = 1 assertEqual(2, eins + 1) assertEqual('11', eins + '1') var liste = [1, 2, 'drei'] assertEqual('drei', liste[2]) var isBig = eins > 1000 if (isBig) fail()
  • 22. JavaScript - Objekte var johannes = new Object(); johannes.firstName = quot;Johannesquot; johannes.lastName = quot;Linkquot; johannes.name = function() { return this.firstName + ' ' + this.lastName } assertEqual('Johannes Link', johannes.name()); var johannes = { firstName: 'Johannes', lastName: 'Link', name: function() { return this.firstName + ' ' + this.lastName } }
  • 23. JavaScript - Prototypen (1) function Person(firstName, lastName) { this.firstName = firstName this.lastName = lastName } Person.prototype.name = function() { return this.firstName + ' ' + this.lastName } var johannes = new Person('Johannes', 'Link') assertEqual('Johannes Link', johannes.name()) assertEqual(true, johannes instanceof Person)
  • 24. JavaScript - Prototypen (2) johannes.name = function() { return 'Joe Cartwright' } assertEqual('Joe Cartwright', johannes.name()) function Student(firstName, lastName) { Person.call(this, firstName, lastName); } Student.prototype = new Person(); Student.prototype.name = function() { return this.firstName; } var jannek = new Student('Jannek', 'Link'); assertEqual('Jannek', jannek.name()); assertEqual('Link', jannek.lastName);
  • 25. Ruby • Sprachumfang und Mächtigkeit ähnlich wie bei Groovy • C-Implementierung als Interpreter • „Berühmt“ durch Ruby on Rails • Ausschließlich dynamische Typen • JRuby: Byte-Code und Java- Integration
  • 26. Ruby - Code class Person attr_reader :first_name, :last_name def initialize(first_name, last_name) @first_name = first_name @last_name = last_name end end class Person def name() first_name + quot; quot; + last_name end end johannes = Person.new(quot;Johannesquot;, quot;Linkquot;) assert_equal quot;Johannes Linkquot;, johannes.name
  • 27. Ruby - Blocks def three_times(arg) yield arg yield arg yield arg end three_times (quot;JUGSquot;) { |name| puts quot;Hello, quot; + name } def twice(arg, action) action.call(arg) action.call(arg) end print_ciao = proc { |name| puts quot;Ciao, quot; + name } twice quot;JUGSquot;, print_ciao
  • 28. Ruby - Mixins module Debug def who_am_i quot;#{self.class.name}quot; end end class Person include Debug end johannes = Person.new(quot;Johannesquot;, quot;Linkquot;) assert_equal quot;Personquot;, johannes.who_am_i s = quot;Ein Stringquot; class Array s.extend Debug include Debug assert_equal quot;Stringquot;, s.who_am_i end assert_equal quot;Arrayquot;, [1, 2, 3].who_am_i
  • 29. Ruby Classes are Objects johannes = Person.new(quot;Johannesquot;, quot;Linkquot;) assert_equal Person, johannes.class assert_equal Class, Person.class assert_equal Class, Class.class assert_equal Module, Class.superclass assert_equal Object, Module.superclass class Class alias_method :old_new, :new def new(*args) puts quot;Objekt wird erzeugt...quot; old_new(*args) end end
  • 30. Ruby Events Event Hook Methodenaufruf Kernel::system Methode hinzufügen Module#method_added Unterklasse erzeugen Class#inherited ...
  • 31. Vergleich (1) Groovy JavaScript Ruby / JRuby gering, deutlich groß, Verbreitung mittel, wachsend wachsend gleichbleibend wenig eingebaut, Bibliotheken J2EE + GDK zahlreich /+J2EE viele externe Libs dynamisch, Typisierung dynamisch dynamisch optional statisch Objektorien- Objekte + vollständig vollständig tierung primitive Typen Vererbung klassenbasiert Prototyp-basiert klassenbasiert sehr mächtig MOP gering sehr mächtig++ (ab 1.5)
  • 32. Vergleich (2) Groovy JavaScript Ruby / JRuby gut, aber mit Java-Integration optimal gering prinzp. Problemen Laufzeit- kompilierter interpretiert / interpretiert umgebung Bytecode auf JVM JVM Bytecode Tool- mäßig bis gut mäßig mäßig bis gut Unterstützung (IDEA) Typisches Scripting in Java- Ajax im Browser Ruby on Rails Anwendungsfeld Applikationen langsam, besser Performance langsam meist ausreichend werdend http://shootout.alioth.debian.org/
  • 33. Strack Trace Java Thread [main] (Suspended (breakpoint at line 22 in JavaPerson)) JavaPerson.doubleName() line: 22 JavaTester.run() line: 7 Tester.test(Class<Runnable>) line: 16 Tester.main(String[]) line: 6
  • 34. Stack Trace Groovy Thread [main] (Suspended (breakpoint at line 18 in GroovyPerson)) GroovyPerson.doubleName() line: 18 NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) NativeMethodAccessorImpl.invoke(Object, Object[]) line: 39 DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 25 Method.invoke(Object, Object...) line: 585 CachedMethod.invoke(Object, Object[]) line: 95 MetaClassHelper.doMethodInvoke(Object, MetaMethod, Object[]) line: 599 MetaClassImpl.invokeMethod(Class, Object, String, Object[], boolean, boolean) line: 904 MetaClassImpl.invokeMethod(Object, String, Object[]) line: 740 InvokerHelper.invokePogoMethod(Object, String, Object) line: 773 InvokerHelper.invokeMethod(Object, String, Object) line: 753 ScriptBytecodeAdapter.invokeMethodN(Class, Object, String, Object[]) line: 167 ScriptBytecodeAdapter.invokeMethod0(Class, Object, String) line: 195 GroovyTester.run() line: 7 Tester.test(Class<Runnable>) line: 16 Tester.main(String[]) line: 7
  • 35. Warum gerade jetzt? • Normale Pendelschwingung zwischen dynamischer und statischer Typisierung • Frust über Redundanz und wachsende Komplexität von Java • Domänen-spezifische Sprachen sind auf dem Vormarsch • Multi-Sprachen-Systeme werden hoffähig • Mehr Wissen über sinnvolle Einsatzszenarien der unterschiedlichen Programmiersprachen
  • 36. Einsatzmuster für Scripting (von Dierk König) • Alleskleber • Weiches Herz • Kluge Anpassung • Endoskopische Operation • Grenzenlose Offenheit • Heinzelmännchen • Prototyp
  • 37. Einsatzmuster: Alleskleber • Applikationen aus bestehenden Komponenten zusammenbauen • Java und .NET sind gut geeignet für stabile Infrastruktur: Middleware, Frameworks, Widget Sets, Services • Scripting ist gut geeignet für flexible View- und Controller-Schichten (z.B. Grails)
  • 38. Alleskleber Demo: RSS Reader • Zusammenbau von XML Parser, Java Networking und Swing Widget Bibliothek, um einen Standard-RSS Feed darzustellen
  • 39. Einsatzmuster: Weiches Herz • Fachliche Modelle auslagern bei vorgegebenem Java-Applikationsgerüst • Fachlichen Erkenntnisfortschritt ermöglichen: Entitäten, Beziehungen und Verhalten bleiben durch Scripting flexibel • Verhaltensänderung zur Laufzeit
  • 40. Weiches Herz Beispiel: Bonusberechnung umsatz = mitarbeiter.umsatz switch(umsatz / 1000) { case 0..100: return umsatz * 0.04 case 100..200: return umsatz * 0.05 case {it > 200}: bonusClub.add(mitarbeiter) return umsatz * 0.06 } Binding binding = new Binding(); binding.setVariable(quot;mitarbeiterquot;, mitarbeiter); binding.setVariable(quot;bonusClubquot;, bonusClub); GroovyShell shell = new GroovyShell(binding); File script = new File(filename); BigDecimal bonus = (BigDecimal) shell.evaluate(script);
  • 41. Einsatzmuster: Kluge Anpassung • Konfigurationen mit Ausführungs-Logik als Ersatz für XML-Konfigurationen • Mit Referenzen, Schleifen, Bedingungen, Vererbung, Ausführungslogik, Umgebungsermittlung, ... • Typischer Anwendungsfall für domänen- spezifische Sprachen (DSLs) • Veränderungen durch den Experten
  • 42. DSL-Beispiel (Bernd Schiffer): Entfernungsberechnung assert 5001.m == 2000.m + 3.km + 1.m class Distance { def meter assert werteAus('5002 m == 2000 m + 3 km + 2 m') def plus(other) { new Distance(meter: meter + other.meter) def werteAus(String ausdruck) { } boolean equals(other) { Eval.me( this.meter == other.meter } ausdruck.replaceAll(quot; (m|km)quot;, { } alle, einheit -> quot;.${einheit}quot; })) class DistanceCategory { } static def getM(distance) { new Distance(meter: distance) } static def getKm(distance) { new Distance(meter: distance * 1000) } }
  • 43. Einsatzmuster: Endoskopische Operation • Minimal-invasive Eingriffe quot;in vivoquot; • Viele Notwendigkeiten für Anpassungen ad-hoc Anfragen sind nicht vorhersehbar • Schlüsselloch für die Live Ausführung von Scripts schaffen, z.B. in einem speziellen Servlet • Unglaublich wertvoll für Produkt-Support, Fehleranalyse, Hot-Fixes, Notfälle
  • 44. Endoskopische Operation: im Servlet Probleme mit der Datenbank Verbindung? def ds = Config.dataSource ds.connection = new DebugConnection(ds.connection) Gefährliche Benutzer rauswerfen users = servletContext.getAttribute('users') bad = users.findAll { user -> user.cart.items.any { it.price < 0 } } servletContext.setAttribute('users', users - bad)
  • 45. Einsatzmuster: Grenzenlose Offenheit • Jede Zeile Code wird änderbar • Manchmal sind die vorgesehenen Variationspunkte nicht ausreichend • Einfache Änderungen ohne langwieriges Setup für Kompilation und Deployment • Perl, PHP, Python, etc. machen es vor
  • 46. Einsatzmuster: Heinzelmännchen • Repetitive Aufgaben automatisieren • Automatisierter Build, kontinuierliche Integration, Deployment, Installationen, Server-Überwachung, Reports, Statistiken, Erzeugen von Dokumentation, funktionale Tests uvm. • Anwendungen mit Ant, Maven und Co.
  • 47. Heinzelmännchen: Mail schicken def users = [ [name:'Johannes', email:'jux@johanneslink.net'], [name:'Teilnehmer', email:'wer@wo.net']] def ant = new groovy.util.AntBuilder() for (user in users) { ant.mail(mailhost: 'smtp.googlemail.com', mailport: '465', ssl: 'true', user: quot;$mailUserquot;, password: quot;$passwordquot;, subject: 'Vortrag ist bald fertig') { from(address: 'johannes.link@googlemail.com') to(address: user.email) message( quot;quot;quot; Hallo ${user.name}, Der Vortrag ist fast fertig: ${new Date().toGMTString()} quot;quot;quot; ) } }
  • 48. Einsatzmuster: Prototyp • Machbarkeitsstudien auf der Zielplattform • quot;Spikesquot; für technologische oder algorithmische Ideen mit besserer Ausdrucksmächtigkeit, schnellerem Feedback und besseren Analysemöglichkeiten • Wahlmöglichkeit für spätere (Teil-) Portierung nach Java / C#
  • 49. Weitere Informationen • Groovy: • http://groovy.codehaus.org/ • Dierk König et al: „Groovy in Action“ • JavaScript: • http://developer.mozilla.org/en/docs/JavaScript • David Flanagan: „JavaScript: The Definitive Guide“ • Microsoft: „ JScript Deviations from ES3“ • Ruby: • http://www.ruby-lang.org • Dave Thomas et al.: „Programming Ruby: The Pragmatic Programmers' Guide“ • http://www.nealford.com/downloads/conferences/ Neal_Ford-Comparing_Groovy_and_JRuby-slides.pdf
  • 50. Zusammenfassung • Java - und andere Entreprise-Plattformen - haben Einschränkungen: • Anpassungen zur Laufzeit • Präzision im Ausdruck • Erweiterbarkeit der Sprache • Dynamische Skriptsprachen sind in diesen Punkten flexibler und mächtiger • bringen jedoch andere Probleme mit sich • Nicht statisch vs dynamisch, sondern...