SlideShare ist ein Scribd-Unternehmen logo
1 von 51
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

Weitere ähnliche Inhalte

Was ist angesagt?

L Sungs Vorschlag Seite15
L Sungs Vorschlag Seite15L Sungs Vorschlag Seite15
L Sungs Vorschlag Seite15
Betablocker
 

Was ist angesagt? (20)

Praesentation TYPO3Camp Berlin Speed mit Extbase
Praesentation TYPO3Camp Berlin Speed mit ExtbasePraesentation TYPO3Camp Berlin Speed mit Extbase
Praesentation TYPO3Camp Berlin Speed mit Extbase
 
P6kontext2014
P6kontext2014P6kontext2014
P6kontext2014
 
Perl 5.20: Feature, Kultur, Module, Werkzeuge
Perl 5.20: Feature, Kultur, Module, WerkzeugePerl 5.20: Feature, Kultur, Module, Werkzeuge
Perl 5.20: Feature, Kultur, Module, Werkzeuge
 
Perl 5 Quiz Chemnitz Edition
Perl 5 Quiz Chemnitz EditionPerl 5 Quiz Chemnitz Edition
Perl 5 Quiz Chemnitz Edition
 
L Sungs Vorschlag Seite15
L Sungs Vorschlag Seite15L Sungs Vorschlag Seite15
L Sungs Vorschlag Seite15
 
Von Java Zu Groovy
Von Java Zu GroovyVon Java Zu Groovy
Von Java Zu Groovy
 
P6oo
P6ooP6oo
P6oo
 
Guava - Google Core Libraries for Java 1.5+
Guava - Google Core Libraries for Java 1.5+Guava - Google Core Libraries for Java 1.5+
Guava - Google Core Libraries for Java 1.5+
 
Python crash-kurs
Python crash-kursPython crash-kurs
Python crash-kurs
 
OpenLDAP - A developer's perspective
OpenLDAP - A developer's perspectiveOpenLDAP - A developer's perspective
OpenLDAP - A developer's perspective
 
Drupal Entities
Drupal EntitiesDrupal Entities
Drupal Entities
 
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...
Battle of the Languages: Java und Python im Wettstreit beim Lösen von Program...
 
Java Persistence 2.0
Java Persistence 2.0Java Persistence 2.0
Java Persistence 2.0
 
Scala
ScalaScala
Scala
 
2013-09-12, sfugcgn: CSS-Selektoren für Datenbankabfragen nutzen
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
 
Ruby on Rails SS09 08
Ruby on Rails SS09 08Ruby on Rails SS09 08
Ruby on Rails SS09 08
 
Ruby on Rails SS09 05
Ruby on Rails SS09 05Ruby on Rails SS09 05
Ruby on Rails SS09 05
 
Codesmells
CodesmellsCodesmells
Codesmells
 
AdvancedTdd
AdvancedTddAdvancedTdd
AdvancedTdd
 
PHP_Codesniffer
PHP_CodesnifferPHP_Codesniffer
PHP_Codesniffer
 

Andere mochten auch

Andere mochten auch (16)

LibGuides and Evolving Learning Spaces
LibGuides and Evolving Learning SpacesLibGuides and Evolving Learning Spaces
LibGuides and Evolving Learning Spaces
 
Mehr Dynamik Mit Groovy
Mehr Dynamik Mit GroovyMehr Dynamik Mit Groovy
Mehr Dynamik Mit Groovy
 
Problem Based Learning - PBL, an introduction
Problem Based Learning - PBL, an introductionProblem Based Learning - PBL, an introduction
Problem Based Learning - PBL, an introduction
 
Mein paralleles Leben als Java-Entwickler
Mein paralleles Leben als Java-EntwicklerMein paralleles Leben als Java-Entwickler
Mein paralleles Leben als Java-Entwickler
 
Ripple Effect: Faculty Redesign Through Course Redesign
Ripple Effect: Faculty Redesign Through Course RedesignRipple Effect: Faculty Redesign Through Course Redesign
Ripple Effect: Faculty Redesign Through Course Redesign
 
The Writing Initiative: Granted, Technology Makes Better Writers
The Writing Initiative: Granted, Technology Makes Better WritersThe Writing Initiative: Granted, Technology Makes Better Writers
The Writing Initiative: Granted, Technology Makes Better Writers
 
30 Quotations Volume 2
30 Quotations Volume 230 Quotations Volume 2
30 Quotations Volume 2
 
Agile08: Test Driven Ajax
Agile08: Test Driven AjaxAgile08: Test Driven Ajax
Agile08: Test Driven Ajax
 
Technology Ethics: An Oxymoron?
Technology Ethics: An Oxymoron?Technology Ethics: An Oxymoron?
Technology Ethics: An Oxymoron?
 
Making Learning Visible
Making Learning VisibleMaking Learning Visible
Making Learning Visible
 
Blogging As Pedagogic Practice Across the Curriculum
Blogging As Pedagogic Practice Across the CurriculumBlogging As Pedagogic Practice Across the Curriculum
Blogging As Pedagogic Practice Across the Curriculum
 
Academia and the MOOC
Academia and the MOOCAcademia and the MOOC
Academia and the MOOC
 
Technical Writing Across Disciplines
Technical Writing Across DisciplinesTechnical Writing Across Disciplines
Technical Writing Across Disciplines
 
Adopting Open Textbooks
Adopting Open TextbooksAdopting Open Textbooks
Adopting Open Textbooks
 
2013: The Beginning of the End of the University
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
 
Rubrics: Transparent Assessment in Support of Learning
Rubrics: Transparent Assessment in Support of LearningRubrics: Transparent Assessment in Support of Learning
Rubrics: Transparent Assessment in Support of Learning
 

Ähnlich wie Mehr Dynamik Durch Skriptsprachen

Webcon 2012 Mobile Development mit Sencha Touch
Webcon 2012  Mobile Development mit Sencha TouchWebcon 2012  Mobile Development mit Sencha Touch
Webcon 2012 Mobile Development mit Sencha Touch
Thorsten Suckow-Homberg
 
Vermisste Sprachfeatures in Java (german)
Vermisste Sprachfeatures in Java (german)Vermisste Sprachfeatures in Java (german)
Vermisste Sprachfeatures in Java (german)
Sven Efftinge
 
Creasoft - Windows powershell
Creasoft - Windows powershellCreasoft - Windows powershell
Creasoft - Windows powershell
Creasoft AG
 
Vorlesung 7: Laufzeit, Maps
Vorlesung 7: Laufzeit, MapsVorlesung 7: Laufzeit, Maps
Vorlesung 7: Laufzeit, Maps
Michael Zilske
 

Ähnlich wie Mehr Dynamik Durch Skriptsprachen (20)

SOLID Prinzipien, Designgrundlagen objektorientierter Systeme
SOLID Prinzipien, Designgrundlagen objektorientierter SystemeSOLID Prinzipien, Designgrundlagen objektorientierter Systeme
SOLID Prinzipien, Designgrundlagen objektorientierter Systeme
 
Pyparsing
PyparsingPyparsing
Pyparsing
 
Webcon 2012 Mobile Development mit Sencha Touch
Webcon 2012  Mobile Development mit Sencha TouchWebcon 2012  Mobile Development mit Sencha Touch
Webcon 2012 Mobile Development mit Sencha Touch
 
PostgreSQL: Eigene Aggregate schreiben
PostgreSQL: Eigene Aggregate schreibenPostgreSQL: Eigene Aggregate schreiben
PostgreSQL: Eigene Aggregate schreiben
 
TypeScript
TypeScriptTypeScript
TypeScript
 
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)
Apache CouchDB at PHPUG Karlsruhe, Germany (Jan 27th 2009)
 
Let’s groove with Groovy
Let’s groove with GroovyLet’s groove with Groovy
Let’s groove with Groovy
 
Vermisste Sprachfeatures in Java (german)
Vermisste Sprachfeatures in Java (german)Vermisste Sprachfeatures in Java (german)
Vermisste Sprachfeatures in Java (german)
 
Php Schulung
Php SchulungPhp Schulung
Php Schulung
 
Go - Googles Sprache für skalierbare Systeme
Go - Googles Sprache für skalierbare SystemeGo - Googles Sprache für skalierbare Systeme
Go - Googles Sprache für skalierbare Systeme
 
.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
.NET Summit 2016 München: EcmaScript 2015+ with TypeScript
 
Modern angular 02_angular_mit_type_script
Modern angular 02_angular_mit_type_scriptModern angular 02_angular_mit_type_script
Modern angular 02_angular_mit_type_script
 
Tech Talk: Groovy
Tech Talk: GroovyTech Talk: Groovy
Tech Talk: Groovy
 
Einführung in Scala im Vergleich mit Java
Einführung in Scala im Vergleich mit JavaEinführung in Scala im Vergleich mit Java
Einführung in Scala im Vergleich mit Java
 
Typescript
TypescriptTypescript
Typescript
 
Creasoft - Windows powershell
Creasoft - Windows powershellCreasoft - Windows powershell
Creasoft - Windows powershell
 
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...
Java Code Quality: Gute Software braucht guten Code - Regeln für verständlich...
 
Performance trotz Entity Framwork
Performance trotz Entity FramworkPerformance trotz Entity Framwork
Performance trotz Entity Framwork
 
Vorlesung 7: Laufzeit, Maps
Vorlesung 7: Laufzeit, MapsVorlesung 7: Laufzeit, Maps
Vorlesung 7: Laufzeit, Maps
 
JsUnconf 2014
JsUnconf 2014JsUnconf 2014
JsUnconf 2014
 

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...