Implementierung
Ziel dieser Phase ist es, die Entwurfsergebnisse der vorhergegangenen Phase
in Programme zu transformieren, die auf einem bestimmten Zielrechner ausführbar
sind. Eine gute Implementierung ist dadurch gekennzeichnet, dass sich in
ihr die Entwurfsentscheidungen spiegeln. Z. B. sollen
-
die beim Entwurf gewählten und festgelegten Zerlegungsstrukturen,
Datenstrukturen und Bezeichner leicht erkennbar wiederzufinden sein,
-
die Abstraktionsebenen des Entwurfes (Klassen, Module, Objekte, Algorithmen,
Datenstrukturen und Datentypen) auch in der Implementierung realisierbar
sein,
-
die Schnittstellen zwischen den Teilen eines Programmsystems explizit beschrieben
sein,
-
die Konsistenz von Objekten und Operationen bereits zur Übersetzungszeit
vom Compiler überprüft werden können.
Die Erfüllung dieser Forderungen hängt sowohl von der gewählten
Programmiersprache wie vom Programmierstil
ab.
Wahl der Programmiersprache
Es gibt zahlreiche, verschiedene Programmiersprachen. Zu den bekanntesten
gehören (in alphabetischer Reihenfolge): Ada, Algol, APL, Basic, C,
C++, Chill, Clu, Cobol, Eiffel, Fortran, Java, Lisp, Modula, Oberon, Pascal,
PL-1, Smalltalk, ... Es gibt aber noch viele andere. Die Frage nach der
"richtigen" Programmiersprache ist schon seit jeher eine beliebtes
und immer wiederkehrendes Thema in Programmiererkreisen, ein echter Evergreen.
Die Entscheidung eines Projekts für eine bestimmte Sprache spielt
in der Tat eine wichtige Rolle. Jeder Programmiersprache liegt nämlich
ein bestimmtes Denkmodell zugrunde, das den beim Entwurf zu bestimmenden
Lösungsweg entscheidend mitbestimmt. Verfügbarkeit oder Fehlen
einzelner Sprachelemente kann zu völlig verschiedenen Entwürfen
führen: Ein Basic-Programmierer wird nicht auf die Idee kommen, abstrakte
Datentypen zu verwenden, ein Fortran-Programmierer wird im Entwurf rekursive
Algorithmen vermeiden, weil Fortran rekursive Prozeduren nicht vorsieht.
Dieser starke Einfluss der Implementierungssprache auf den Entwurf führt
meist zu einer frühzeitigen Auswahl der Sprache bei Projektbeginn.
Häufig ist die Wahl der Sprache auch gar keine Projektentscheidung,
sondern wird durch andere äußere Umstände wie z.B. Forderung
des Auftraggebers oder Verfügbarkeit (Lizenzen, ..) einer Entwicklungsumgebung
vorgegeben.
Im folgenden werden einige Kriterien angegeben, die Einfluss auf die
Sprachauswahl haben sollten.
Qualitätskriterien für Programmiersprachen
Zu den wichtigsten gehören:
-
Modularität
-
erlaubt die Zerlegung eines Programmes in kleinere Einheiten, die Schnittstellenbeschreibungen
besitzen und getrennt übersetzt werden. Die Einhaltung der Schnittstellenvereinbarung
sollten dabei schon bei der Übersetzung eines Moduls geprüft
werden (z.B. bei Modula, Ada, Chill) und nicht erst beim Zusammenfügen
der Module.
-
Dokumentationswert
-
beinflusst Lesbarkeit und Wartbarkeit. Besonders wichtig ist dabei die
Trennung von Schnittstellenbeschreibung und Implementierung. In der Sprache
Java ist diese Trennung nicht vorgesehen, um Redundanzen zwischen Header-Dateien
und Implementierungsdateien zu vermeiden. Stattdessen wird dort die Schnittstellenbeschreibung
aus dem Quelltext und speziellen Dokumentationskommentaren mt Hilfe eines
Werkzeuges (javadoc) erzeugt .
-
Datenstrukturen
-
sind für die Verarbeitung komplexer Daten enorm wichtig. Ältere
Sprachen stellen nur Felder (Zusammenfassung gleichartiger Elemente) oder
Strukturen aus verschiedenartigen Elementen zur Verfügung. Darüber
hinaus gehen rekursive und dynamische Datenstrukturen. Abstrakte Datenstrukturen
können zwar in jeder modularen Sprache nachgebildet werden, vorzuziehen
sind aber solche, die diese direkt unterstützen. Bei objekt-orientierten
Sprachen ist dies der Fall, mit ihnen lassen sich auch erweiterbare
abstrakte Datentypen mit geringem Aufwand realisieren.
-
Ablaufsteuerung
-
umfaßt nicht nur die fast immer vorhandenen klassischen Konstrukte
Sequenz, Verzweigung und Wiederholung für sequentielle Programme,
sondern auch die Frage, ob eine Goto-Anweisung existiert, ihre Verwendung
erschwert wird oder überhaupt nicht vorhanden ist. Weitere wichtige
Elemente sind Sprachkonstrukte zur Ausnahmebehandlung, zur Interrupt-Behandlung
und zur Definition und Synchronisation nebenläufiger Prozesse und/oder
Threads.
-
Effizienz
-
von Programmiersprachen wird meist als Kriterium überschätzt.
So hat z.B. die Sprache C den Ruf, dass man in ihr sehr effiziente Programme
schreiben kann, während objekt-orientierten Sprachen Ineffizienz nachgesagt
wird. Man kann aber nur in wenigen Fällen sagen, dass eine Sprache
vom Prinzip her besonders effizient oder ineffizient sei. Optimierende
Compiler erzeugen oft hervorragenden Code, der von erfahrenen Assembler-Programmierern
kaum besser geschrieben werden könnte. Geht es um zeitkritische Operationen,
ist es daher meist besser, sich nach einem schnelleren Rechner oder einem
besserem Compiler umzusehen, statt eine "effiziente " Sprache zu verwenden.
-
Sicherheit
-
einer Programmiersprache umfasst ihre Lesbarkeit, aber auch ihre Mechanismen
zur (modulübergreifenden) Typprüfung, die am besten schon zur
Übersetzungszeit vom Compiler vorgenommen wird. Was nicht zur Laufzeit
geprüft werden kann, wie z.B. Überschreitung von Feldgrenzen,
sollte in Laufzeitprüfungen umsetzbar sein. Auch benutzerdefinierte
Laufzeitprüfungen wie z.B. Assertionen (direkt unterstützt in
Eiffel, in C kann man das assert-Makro verwenden!) erhöhen die Sicherheit.
Weitere Sicherheitsrisiken sind Typkonvertierungen und "freie" Zeiger.
Die Programmiersprache Java schenkt diesen Sicherheitsaspekten besondere
Aufmerksamkeit.
-
Portabilität
-
kann wichtig werden, wenn das geplante Produkt auf mehreren Plattformen
eingesetzt werden soll. Dann empfiehlt sich eine normierte Sprache wie
z.B. Ada oder ANSI-C. Darüberhinaus müssen natürlich auch
die verwendeten Bibliotheken für alle benötigten Plattformen
vorliegen, ebenso die Compiler.
-
Dialogtauglichkeit
-
wird für interaktive Programme benötigt. Dies ist aber zumeist
keine Eigenschaft der Sprache, sondern der Bibliotheken, die zum "Standardumfang"
der Sprache gehören. Z.B. bei objekt-orientierten Sprachen gehören
entsprechende Klassenbibliotheken einfach dazu.
-
Spezielle Sprachelemente
-
können auch den Auschlag für die Wahl der Programmiersprache
sein. Beispiele sind komplexzahlige Arithmetik (in Fortran), Festkommazahlen
mit grossen Wertebereichen (Cobol), Matrixoperation (APL) usw.. Objekt-orientierte
Sprachen können meist aber diese speziellen Sprachelemente durch selbst
definierte Klassen bereitstellen.
Externe Einflussfaktoren
Dazu gehören Qualität des Compilers, Verfügbarkeit und Qualität
von Bibliotheken und Entwicklungswerkzeugen, Firmenpolitik und externe
Anforderungen.
Programmierstil
Die Lesbarkeit eines Programmes hängt auch von der verwendeten Programmiersprache
ab, in weitaus größerem Maße aber vom Programmierstil
des Implementierers. Lesbare Programme zu schreiben, ist ein kreativer
Prozess. Ein stilistisch gut geschriebenes Fortran- oder Cobol-Programm
kann besser lesbar sein als ein schlecht geschriebenes Modula-2- oder Java-Programm.
Die wichtigsten Stilelemente sind:
-
Strukturiertheit
-
im Großen: sie zielt darauf ab, die im Entwurf gefundene, einfache,
verständliche und angemessene Zerlegung des Problems innerhalb des
Programmtextes klar und deutlich auszudrücken. Dies hängt naturlich
davon ab, ob die gefundene Zerlegung in Klassen, Objekte oder Module in
der Programmiersprache angemessen dargestellt werden kann.
-
im Kleinen meint, ausschließlich die Konstrukte der strukturierten
Programmierung (Sequenz, Verzweigung und Wiederholung) zu verwenden.
-
Ausdruckskraft
-
bei der Wahl von Namen für Objekte und Operationen ist ein ganz wesentliches
und leider häufig in seiner Wichtigkeit unterschätztes Stilelement.
Ein Name wie WPSMHGW (GrenzWert für das Projekt
WärmePumpenSteuerung, Programmierer: Maier
Hans) ist auf jeden Fall zu vermeiden. Es empfehlen sich folgende
allgemeine Regeln, detailliertere Regeln werden in projekt-, sprach- oder
firmenspezifischen Programmierrichtlinien festgelegt:
-
Aussagekräftige Name wählen, auch wenn sie lang werden. Bei lokalen
Namen, für die Definition und Verwendung nahe beieinander liegen,
können kürzere Namen verwendet werden.
-
Nur allgemein übliche Abkürzungen verwenden, Abkürzungen
immer im gleichen Sinne verwenden (nicht temp für temporär und
für Temperatur).
-
Innerhalb des Programmsystems nur Namen einer Sprache verwenden, also entweder
deutsche oder englische.
-
Groß- und Kleinschreibung zur Unterscheidung verschiedener Arten
von Bezeichnern verwenden (z.B. große Anfangsbuchstaben für
Klassen, kleine für Objekte und Operationen, nur Großbuchstaben
für Konstanten). Dadurch werden lange Namen besser lesbar (z.B. holeEingabeWert).
-
Hauptwörter für Werte und Objekte, Zeitworte für Tätigkeiten
und Eigenschaftsworte für Bedingungen (z.B. breite, leseSchlüssel,
istGültig).
-
Präzise Kommentare richtig und gezielt einzusetzen ist ebenfalls eine
Kunst. Einige allgemeine Regeln sind:
-
Jede Systemkomponente beginnt mit einem ausführlichen Kommentar, der
dem Leser Auskunft zu folgenden Fragen gibt:
-
Was leistet die Komponente?
-
Wozu wird die Komponente verwendet?
-
Welche Verfahren, spezielle Methoden werden benutzt?
-
Verfasser? Erstellungsdatum? Version?
-
Welche Änderungen wurden bereits wann, von wem, warum vorgenommen
(Change Log)?
-
Jede Definition einer Prozedur, Methode besitzt einen Kommentar, der ihre
Aufgabe und evtl. ihre Arbeitsweise beschreibt. Analog für Variable.
-
Schwer verständliche Programmteile (z.B. trickreiche Verfahren oder
Ausnutzung von Besonderheiten eines bestimmten Computers) werden für
den Leser verständlich kommentiert.
-
Ganz allgemein enthält ein Programm nur so wenige und so knappe Kommentare
wie möglich, aber so viele und so ausführliche wie nötig.
Kommentare der Art "Dies ist eine Methode" o.ä. sind kontraproduktiv
und nervtötend!
-
Änderungen am Programmtext werden immer zusammen mit den
zugehörigen Kommentare vorgenommen. Falsche Kommentare sind schlechter
als überhaupt keine.
-
Für Java's Dokumentationskommentare gibt es speziellere und genauere
Richtlinien.
-
Äußere Form
-
Auch dies wird üblicherweise in Programmierrichtlinien (Coding Guidelines)
detailliert festgelegt. Allgemeine Regeln sind:
-
Deklarationsteil und Anweisungsteil deutlich trennen
-
Deklarationsteile nach einheitlichem Gliederungsschema anlegen, z.B. in
der Reihenfolge Konstanten, Datentypen,Variablen, Klassen und Module, Methoden
und Prozeduren.
-
Die Schnittstellenbeschreibung (Parameterliste von Prozeduren/Methoden)
trennt deutlich zwischen Eingangs- ausgangs- und Übergabeparametern.
-
Kommentare und Programmtext sind deutlich voneinander zu trennen.
-
Programmstruktur wird durch Einrückung deutlich gemacht.