article

Die Generative Programmierung ist ein besonderes Programmierparadigma bei der methodischen Softwareentwicklung. Charakteristisch für die generative Programmierung ist die automatische Erzeugung von Programmcode durch einen Generator.

Funktionsweise eines Programmgenerators


Ein Programmgenerator kann am besten wie ein gewöhnliches Programm nach dem EVA-Prinzip verstanden werden. Aufgrund bestimmter Inputparameter erzeugt der Programmgenerator einen bestimmten Output. Allerdings ist der Output eines generativen Programms wiederum ein Programmcode, nämlich der Code, welcher für die konkretisierte Situation ausgeführt werden soll.

Grundlage für automatisch erzeugten Code ist die Abstraktion häufig vorkommender Programmkonstrukte in formalen Modellen. Die Programmierung unterteilt sich in drei Phasen:

  1. Der Programmierung eines bestimmten Programmgenerators
  2. Der Parametrierung oder Ergänzung und Konfiguration des formalen Modells, auf eine spezifische Modellausprägung
  3. Dem Aufruf des Programmgenerators mit den spezifischen Inputparametern, welcher dann das spezifische Zielprogramm erstellt

Ein Programmgenerator bzw. Codegenerator ist demnach auf eine generische Anwendungs- und Programmklasse spezialisiert. Er bezieht sich auf ein bestimmtes, zugrundeliegende generisches Programmodell, aus welchem er nach konkretisierender Parameterisierung den Zielcode erzeugt. Dies kann ein Quellcode, Zwischencode oder Binärcode sein.

Während ein normales, funktional programmiertes Programm die Varianz der Aufgabenstellungen ausschließlich mit Datenvariablen abdeckt, arbeitet die generative Programmierung auch mit variabilisiertem Programmcode, der erst im Hinblick auf den Zielcode eindeutig ausgeprägt wird.

Dieses Vorgehen eignet sich besonders für Problemlösungen, die in entsprechend großer Zahl von Variationen in der Praxis vorkommen, da für die Erstellung des Modells und des Generators ein nicht geringer Aufwand eingeplant werden muss. Dieser Aufwand kann sich aufgrund höherer Qualität des Programmcodes und kürzerer Enwicklungszeit amortisieren. Häufig werden die Zielprogramme nur temporär zum einmaligen Gebrauch generiert und danach wieder gelöscht. Dadurch kann der zu einem bestimmten Zeitpunkt persitent vorhandene Programmcode, z.B. gemessen anhand Anzahl Codezeilen, ggf. um einige Zehnerpotenzen reduziert werden.

Generative Programmierung ist überall dort sinnvoll, wo bestimmte Codeteile analog variablen Textbausteinen zu einer abzählbaren oder nicht mehr abzählbaren Vielzahl von Zielprogrammen zusammengefügt werden sollen. Die generative Programmierung erlaubt im weiteren auch die Erstellung von Zielprogrammen, deren Zielparameter zum Zeitpunkt der Codierung des Programmgenerators noch gar nicht bekannt sind.

Persistenter Zielcode

Der von einem Programmcode erzeugte Zielcodes kann
  • einmal erzeugt, persistent gespeichert und dann permant genutzt werden, oder
  • nach Bedarf dynamisch erzeugt und ausgeführt und danach wieder gelöscht werden

Wenn ein Zielcode einmal erzeugt und dann persistent gehalten wird, kann die Programmgenerierung und die Ausführung des Zielprogramms zeitlich entkoppelt stattfinden. Das Ereignisse der Programmgenerierung und der Ausführung des Zielprogramms sind hier nur insofern voneinander abhängig, dass die Generierung vor der Ausführung des Zielcodes stattfindet. Die Codegenerierung wird dann typischerweise vom Programmierer oder vom einem Systemadministrator bei der Softwareinstallation angestoßen. Also einer anderen Person als dem Endbenutzer, der das Programm letztendlich nutzt.

Bsp: Ein Programmgenerator (Codewizard) zur Erstellung des Basiscode einer Programmklasse, fragt verschiedene Parameter ab, wie Klassennamen, Anzahl, Namen und Type der Klasseneigenschaften, Anzahl und Namen der Klassenmethoden und erstellt dann den Programmcode der Klasse.

Eine Neugenerierung ist nur dann notwendig, wenn sich Änderungen an den Generierungsparametern ergeben.

Dynamisch erzeugter Zielcode

Im zweiten Fall wird die Programmgenerierung und die Ausführung des Zielcodes in der Regel direkt vom Endbenutzer angestoßen. Dabei erfolgt die Programmgenerierung idealerweise so schnell, dass der Endbenutzer gar nicht merkt, dass der von ihm genutzte Programmteil erst vor wenigen Sekundenbruchteilen automatisch ausprogrammiert worden ist. Der Ablauf dieses dynamischen Vorgangs soll in einzelnen Schritten nachvollzogenen werden:
  1. Der Anwender macht eine Auswahl der Eingangsparameter, z.B den Namen einer Datenbanktabelle
  2. Der Programmgenerator nimmt den Tabellennamen vom Endbenutzer, liest aus dem Datadictionary der Datenbank die Felder, Feldtypen und Fremdschlüsselbeziehungen und erzeugt aus diesen Steuerparametern den Programmzielcode eines Suchformulars zur Datenanzeige für die vom Benutzer vorgegebene Datenbanktabelle.
  3. Der Programmzielcode wird nun kurz compiliert und dann vom Programmgenerator mit einem dynamischen Aufruf ausgeführt.

Der letzte Schritt stellt bestimmte Anforderungen an die verwendete Programmiersprache:

  • Es muss im Programmgenerator möglich sein, eine Routine aufzurufen, deren Namen variabel vorgegeben ist, und im Kontext des Programmgenerators nicht zwingend bekannt ist. (z.B. Vorgabe der aufzurufenden Routine durch eine Stringvariable, Late Binding)
  • Die notwendige Flexibilität in der Programmgenerierung verlangt nach einer interpretierten Sprache, d.h. in der Regel wird als Zielcode ein Interpretercode erzeugt und nicht ein Maschinencode.

  1. Der Parametrierung oder Ergänzung des formalen Modells, auf eine spezifische Modellausprägung
  2. Dem Aufruf des Programmgenerators mit den spezifischen Inputparametern, welcher dann das spezifische Zielprogramm erstellt

Ein Programmgenerator ist demnach ein auf eine generische Anwendungs- und Programmklasse spezialisierter Codegenerator. Er bezieht sich auf ein bestimmtes, zugrundeliegende generisches Programmodell, aus welchem er nach konkretisierender Parameterisierung den Zielcode erzeugt. Dies kann ein Quellcode, Zwischencode oder Binärcode sein.

Anwendungsbeispiele


UML

UML erlaubt die Erstellung einer Softwarearchitektur in Form eines Diagramms. Daraus kann dann automatisch Java-Code erzeugt werden, der dann gewöhnlich "von Hand" vervollständigt werden muss. Anspruchsvollere Entwicklungsumgebungen ermöglichen auch das gleichzeitige Arbeiten auf der UML und Java-Ebene. Man kann so wahlweise den UML oder den Java-Code verändern und die Entwicklungsumgebungen erstellt dann automatisch die jeweils andere Darstellung des Programms. Dabei wird also entweder UML-Code aus dem Java-Code generiert oder umgekehrt.

Mit XML und XSLT

Vor allem mit XSLT ist die automatische Codegenerierung sehr einfach und flexibel zu bewerkstelligen. Das gewünschte Modell wird in einem XML-Dokument dargestellt, dessen Syntax man selbst erfinden kann. Dann erstellt man ein zu dem XML-Dokument passendes XSLT-Skript, das den Programmcode generiert. Dies kann auch in einem mehrstufigen Prozess geschehen, z.B. generiert man mit einem ersten XSLT-Skript eine Batchdatei, ein Shellskript oder eine Makefile mit einer Liste weiterer XSLT-Verarbeitungsschritte oder anderer Befehle.

Formulargeneratoren

Anhand einer listenförmigen Beschreibung der Tabellenstruktur, wird jeweils konkret vorgegebenen Tabellen eine Bildschirmmaske erstellt. Aufbau und Funktionsweise des Formulars ist fest vorgegeben. Die verschiedenen Tabellen unterscheiden sich jedoch bezüglich Art und Anzahl der Felder, der Feldbezeichnungen, -typen und Fremdschlüsselbeziehungen.

Compiler-Compiler

Die Syntax einer Programmiersprache wird z.B. in EBNF-Notation vorgegeben. Aufgrund dieser formalen Sprachdefinition erzeugt ein Compiler-Compiler den Compiler, bzw. ein Parsergenerator den Parser für die spezifizierte Sprache. Siehe hierzu auch: Coco/R und yacc.

Produktkonfiguration

Die generative Programmierung kann auch für die Abarbeitung von Stücklisten mit variablen Stücklistenpositionen verwendet werden. Im Rahmen des Customizings oder der Installation können generative Programme die Variantenkonfiguration von komplexen Softwareanwendungen auf die gewünschte Zielform bringen.

Siehe auch


Literatur


  • Czarnecki, Krzysztof; Ulrich W. Eisenecker: Generative Programming: Methods, Tools, and Applications, Addison Wesley, 2000, ISBN 0-201-30977-7

  • Peter Rechenberg; Hanspeter Mössenböck: Ein Compiler-Generator für Mikrocomputer. Grundlagen, Anwendung, Programmierung in Modula-2; Hanser, 1988, ISBN 3-446-15350-0

  • Christof A. Hurst; Ulrich W. Eisenecker: Generative Programmierung für web-orientierte Softwaresystemfamilien, Ein E-/Web-Learning-Projekt Projektbericht (PDF 2MB) Anlage A Anlage B

  • Michael Klar: Einfach generieren. Generative Programmierung verständlich und praxisnah Hanser, 2006, ISBN: 3446404481

Weblinks


  • http://www.codegeneration.net
  • http://gp.informatik.fh-kl.de/
  • http://en.wikipedia.org/wiki/Domain_Specific_Language
  • http://www.hugosweb.de
  • http://www.einfach-generieren.de
Generative programming | Atelier de génie logiciel

Programmierparadigma

 

This article is licensed under the GNU Free Documentation License. It uses material from the "Generative Programmierung".

Home Pageartsbusinesscomputersgameshealthhospitalshomekids & teensnewsphysiciansrecreationreferenceregionalscienceshoppingsocietysportsworld