Strict Standards: Declaration of Walker_Page::start_lvl() should be compatible with Walker::start_lvl(&$output) in /www/htdocs/v167612/wplog/wp-includes/classes.php on line 1199

Strict Standards: Declaration of Walker_Page::end_lvl() should be compatible with Walker::end_lvl(&$output) in /www/htdocs/v167612/wplog/wp-includes/classes.php on line 1199

Strict Standards: Declaration of Walker_Page::start_el() should be compatible with Walker::start_el(&$output) in /www/htdocs/v167612/wplog/wp-includes/classes.php on line 1199

Strict Standards: Declaration of Walker_Page::end_el() should be compatible with Walker::end_el(&$output) in /www/htdocs/v167612/wplog/wp-includes/classes.php on line 1199

Strict Standards: Declaration of Walker_PageDropdown::start_el() should be compatible with Walker::start_el(&$output) in /www/htdocs/v167612/wplog/wp-includes/classes.php on line 1244

Strict Standards: Declaration of Walker_Category::start_lvl() should be compatible with Walker::start_lvl(&$output) in /www/htdocs/v167612/wplog/wp-includes/classes.php on line 1391

Strict Standards: Declaration of Walker_Category::end_lvl() should be compatible with Walker::end_lvl(&$output) in /www/htdocs/v167612/wplog/wp-includes/classes.php on line 1391

Strict Standards: Declaration of Walker_Category::start_el() should be compatible with Walker::start_el(&$output) in /www/htdocs/v167612/wplog/wp-includes/classes.php on line 1391

Strict Standards: Declaration of Walker_Category::end_el() should be compatible with Walker::end_el(&$output) in /www/htdocs/v167612/wplog/wp-includes/classes.php on line 1391

Strict Standards: Declaration of Walker_CategoryDropdown::start_el() should be compatible with Walker::start_el(&$output) in /www/htdocs/v167612/wplog/wp-includes/classes.php on line 1442

Strict Standards: Redefining already defined constructor for class wpdb in /www/htdocs/v167612/wplog/wp-includes/wp-db.php on line 306

Strict Standards: Redefining already defined constructor for class WP_Object_Cache in /www/htdocs/v167612/wplog/wp-includes/cache.php on line 433
iFool » Groovy & Grails
Home > Groovy & Grails > Groovy & Grails

Groovy & Grails

Grails Logo

Webanwendungen zu erstellen kann sehr mühsam sein. Ich hatte in der Verganagenheit häufig Probleme mit

  • komplexer Softwarearchitektur
  • fehlenden Konzepten für eine einheitliche Anwendungsstruktur
  • Entscheidungen für das “richtige” Framework

Webanwendungen spielen aber eine immer größere Rolle im LAN bzw. Intranet auch mittelständischer Betriebe. Wenn ich dort als Systemintegrator unterwegs bin um z.B. unser DMS MultiArchive in die Systemlandschaft zu integrieren habe ich schnell die Anforderung auf dem Tisch kleinere Funktionen als Bindeglieder zwischen den Anwendungssystemen neu zu erstellen. Ein Beispiel: Die Wareneingänge zu einem bestimmten Lieferschein sollen direkt aus dem Browser-Frontend von MultiArchive über ein weiteres Browserfenster angezeigt werden können. Das ERP-System bietet diese Funktion aber nicht!

Jetzt ist guter Rat gefragt, denn eine vergleichsweise kleine Aufgabenstellung kann in diesem Umfeld eine Menge Arbeit verursachen. Je nachdem, wie bzw. womit man die Anferderung umzusetzen gedenkt.

Ich bin vor Kurzem auf Grails aufmerksam geworden. Es basiert auf Groovy, einer auf Java-Technologie aufbauenden Spracherweiterung. Groovy nimmt Java einiges von der Java-Typischen Sperrigkeit. Es vereinfacht und erweitert die Sprache, ohne deren Umfang irgendwie einzuschränken. Alle Java-Klassen, Bibliotheken, Frameworks können wie gewohnt in die eigenen Projekte einbezogen werden und wer es mag kann auch weiterhin innerhalb seiner Groovy-Scripte lupenreinen Java-Code verbauen.

Grails schließlich ist ein Open-Source Webanwendungs-Erstellungswerkzeug das in sich einige der zurzeit angesagtesten Java-Frameworks zusammenfasst und handelt. Der Anwendungsentwickler braucht sich nicht mit jedem Framework das dabei Verwendung findet auseinander setzen. Diese Dinge übernimmt Grails automatisch für ihn. Ein Beispiel: GORM ist das “grails-object-related-mapping” und kümmert sich um die Persistenz der Applikations-Objekte. GORM schlägt dabei unter Verwendung von Hybernate die Brücke zwischen den “lebendigen” Instanzen einzelner Objekte der Anwendung und der verwendeten relationalen Datenbank. Dazu mal hier ein kleines Beispiel:

In einer Anwendung exestieren die Domänen-Klassen “Author” und “Book”. Mit dem folgenden Code lässt sich dann beispielsweise ein neuer Autor mit einem seiner Bücher in die gleichzeitig Datenbank aufnehmen:

def a = new Author(name:“Stephen King”)
def b = new Book(title:“The Shining”,author:b)
a.books.add(b)
a.save()

Okay,- vereinfachungen im Umgang mit Relationalen Datenbanken sind ja ganz nett, aber deshalb schon wieder ein neues Tool nutzen? Natürlich nicht, denn das ist ja erst der Anfang. Grails geht viel weiter und “generiert” beim sogenannten “Scaffolding-Process” komplette Anwendungen mit allen dazu gehörenden Ressourcen. Erstellt werden dabei sogenannte CRUD-Dialoge, die man zur GUI-Verwaltung von Relationen immer benötigt: C=create, R=read, U=update, D=delete.

Wie erstellt man eine solche Anwendung? Das Herz bilden die sogenannten Domain-Classes.  Sie definieren die Businessobjekte und erhalten auch ein Mapping zur zugehörigen Datenbank-Tabelle:

class ItemType {
    long id = -1
    Archive archive
    String itemType
    String aliasItemType
    String descriptionFormula
    String fullText

    static belongsTo = Archive

    static hasMany = [itemTypeFields: ItemTypeField]

    static mapping = {
        table ‘M$SE002PA’
        version false
        id generator: ‘assigned’
        columns {
            archive(column: ‘ARC_ID’)
            itemType(column: ‘ITMTYP’, type: ’string’)
            aliasItemType(column: ‘ALIITMTYP’, type: ’string’)
            descriptionFormula(column: ‘DSCFRM’, type: ’string’)
            fullText(column: ‘FULTXT’, type: ’string’)
        }
    }

    static constraints = {
        id()
        archive()
        itemType(unique:true, blank:false)
        aliasItemType(maxSize:50)
        descriptionFormula(blank:false, maxSize:256)
        fullText(blank:false, maxSize:1,inList:["0", "1"])
    }

    String toString(){
        return itemType + ” (” + archive + “)”
    }
}

Ein paar Erläuterungen zu den Blöcken dieser Domainklasse:

“id, archive, itemType,…,fullText” bezeichnen die Felder (=Attribute) der Klasse.

Nach dem Deklarationsblock kommt mit “belongsTo”  und “hasMany” die Beschreibung des Verhältnisses dieser Domänenklasse zu anderen Klassen. Das ist wichtig, damit Grails erkennt welche Datenbank-Abhängigkeiten bestehen.

Bei “static mapping” wird ein file-field-mapping vorgenommen: Wie heißen zugehörige DB-Tabelle und Felder in der Datenbank?

In “static constraints” werden ein paar Gültigkeitsprüfungen vorgenommen.

Aus einer Anzahl derartiger Klassendefinitionen kann Grails dann bereits eine Application generieren die das Administrations-Interface für die dazugehörigen Datenbank-Tabellen darstellt. Dabei kann der Entwickler über eigene Designs großen Einfluss auf das Design der Anwendung nehmen. Über Plugins die von der Grails-Entwicklergemeinde zur Verfügung gestellt werden lässt sich die Grails Funktionalität noch einmal stark erweitern (z.B. Grafik, Security, Ajacs o.Ä.)

dbrelations_itellij

Die Abbildung zeigt das Beziehungsmodell einer Grails-Anwendung grafisch an. Verwendete Entwicklungsumgebund hier: IntelliJ von JetBrains.

MVC Paradigma

Bei den von Grails generierten Anwendungsskeletten handelt es sich immer um MVC-Anwendungen. Das MVC-Paradigma teilt die Anwendung streng in die Ebenen Model, View und Controller auf um Vermischungen von Businesslogik und Design zu verhindern.

Groovy & Grails ,

  1. Bisher keine Kommentare
  1. Bisher keine Trackbacks