Programmierstil - IPD Snelting
Programmierstil - IPD Snelting
Programmierstil - IPD Snelting
Erfolgreiche ePaper selbst erstellen
Machen Sie aus Ihren PDF Publikationen ein blätterbares Flipbook mit unserer einzigartigen Google optimierten e-Paper Software.
Programmieren<br />
Prof. Dr.-Ing. Gregor <strong>Snelting</strong><br />
Dipl.-Inf. Univ. Andreas Lochbihler<br />
Dipl.-Inform. Denis Lohner<br />
Universität Karlsruhe<br />
Institut für Programmstrukturen und Datenorganisation (<strong>IPD</strong>)<br />
Lehrstuhl Programmierparadigmen<br />
WS 2008/2009<br />
c○2008 by <strong>IPD</strong> <strong>Snelting</strong> / Universität Karlsruhe (TH)
Übersicht<br />
<strong>Programmierstil</strong><br />
1 <strong>Programmierstil</strong><br />
Grundsätzliches<br />
Namen und Kommentare<br />
Programmlayout<br />
Programmstruktur und Lokalität<br />
Weitere Beispiele . . .<br />
Allgemeine Programmertipps<br />
Prof. Dr.-Ing. G. <strong>Snelting</strong> (Uni Karlsruhe) c○2008 by <strong>IPD</strong> <strong>Snelting</strong> – Programmieren WS 2008/2009 2 / 31
<strong>Programmierstil</strong><br />
Grundsätzliches<br />
Warum verständlich programmieren?<br />
Warum legen wir Wert darauf, dass Ihre Programme funktionieren,<br />
und außerdem noch lesbar sind?<br />
Andere lesen Programme<br />
Software-Wartung erzeugt 80% der Kosten<br />
Quelltext ist die einzige verlässliche Dokumentation<br />
Software wird mit Quelltexten ausgeliefert<br />
Java Code Conventions (JCC) als internationaler Standard<br />
Prof. Dr.-Ing. G. <strong>Snelting</strong> (Uni Karlsruhe) c○2008 by <strong>IPD</strong> <strong>Snelting</strong> – Programmieren WS 2008/2009 3 / 31
<strong>Programmierstil</strong><br />
Grundsätzliches<br />
Grundregeln<br />
Halten Sie Ihre Programme<br />
einfach<br />
klar<br />
komplett<br />
konsistent<br />
robust<br />
Preisfrage: Wie erreicht man das?<br />
Prof. Dr.-Ing. G. <strong>Snelting</strong> (Uni Karlsruhe) c○2008 by <strong>IPD</strong> <strong>Snelting</strong> – Programmieren WS 2008/2009 4 / 31
<strong>Programmierstil</strong><br />
Grundsätzliches<br />
Wie schreibe ich ein verständliches Programm?<br />
Fragen an Ihr Programm:<br />
Sind Bezeichner aussagekräftig und konsistent gewählt?<br />
Sind die Komponenten und Verfahren gut dokumentiert?<br />
Wird die Programm-Struktur durch konsistente Einrückung<br />
und Leerzeilen verdeutlicht?<br />
Wird das Verfolgen des Programm-Ablaufs durch kleine,<br />
wohlstrukturierte Prozeduren unterstützt?<br />
Ist jede Komponente so lokal wie möglich gewählt?<br />
Kann das Programm ohne großen Aufwand an veränderte<br />
Randbedingungen angepasst werden?<br />
Prof. Dr.-Ing. G. <strong>Snelting</strong> (Uni Karlsruhe) c○2008 by <strong>IPD</strong> <strong>Snelting</strong> – Programmieren WS 2008/2009 5 / 31
<strong>Programmierstil</strong><br />
Namen und Kommentare<br />
Bezeichner<br />
Sind die Bezeichner aussagekräftig und konsistent gewählt?<br />
Selbsterklärende, eindeutige Namen für Methoden und Variablen<br />
Verwendung einzelner Buchstaben nur als Laufindizes (i, j, k) oder<br />
Parameter einfacher mathematischer Funktionen (x, y, z)<br />
Keine weiteren Informationen im Namen kodiert<br />
Groß/Kleinschreibung (und Unterstriche) zur Trennung von<br />
Wortteilen<br />
Einheitliche Groß/Kleinschreibung für Konstanten, Variablen,<br />
Methoden und Klassen.<br />
Prof. Dr.-Ing. G. <strong>Snelting</strong> (Uni Karlsruhe) c○2008 by <strong>IPD</strong> <strong>Snelting</strong> – Programmieren WS 2008/2009 6 / 31
Beispiel 1<br />
<strong>Programmierstil</strong><br />
Namen und Kommentare<br />
Schlecht:<br />
public static final int CPL = 80;<br />
// Characters per line<br />
oder<br />
public static final int dfgh = 80;<br />
// some buffer variable<br />
Besser:<br />
public static final int CHARACTERS_PER_LINE = 80;<br />
Standard:<br />
String Klasse, beginnend mit Großbuchstaben<br />
MAX SIZE Konstante, durchgehend groß und mit Unterstrich getrennt<br />
arraySize Variable, beginnend mit Kleinbuchstaben<br />
printName Methode, beginnend mit Kleinbuchstaben<br />
Prof. Dr.-Ing. G. <strong>Snelting</strong> (Uni Karlsruhe) c○2008 by <strong>IPD</strong> <strong>Snelting</strong> – Programmieren WS 2008/2009 7 / 31
Dokumentation<br />
<strong>Programmierstil</strong><br />
Namen und Kommentare<br />
Sind die Komponenten und Verfahren gut dokumentiert?<br />
Kommentiert wird genau das, was nicht offensichtlich ist.<br />
der Zweck jeder Klasse, Methode und jeder Variable.<br />
der Zweck von komplizierten Programm-Abschnitten.<br />
Kommentare geben zusätzliche Informationen.<br />
Kommentare bereiten vor und erklären nicht nachträglich.<br />
Kommentare stehen immer vor dem Kommentierten.<br />
Ausnahme: Kurzkommentare<br />
Kommentare und Programmtext sind fortlaufend lesbar.<br />
Kommentare und Programmtext nicht mischen.<br />
Kommentare sind kurz, präzise und verständlich<br />
Prof. Dr.-Ing. G. <strong>Snelting</strong> (Uni Karlsruhe) c○2008 by <strong>IPD</strong> <strong>Snelting</strong> – Programmieren WS 2008/2009 8 / 31
Beispiel 2<br />
<strong>Programmierstil</strong><br />
Namen und Kommentare<br />
Zweck einer Methode<br />
/*<br />
* Return the greatest common divisor of ‘x’ and ‘y’.<br />
* Use the euclidian algorithm.<br />
*/<br />
public static int gcd(int x, int y) { ... }<br />
Zweck einer Anweisung<br />
// recompute the size because the base configuration changed<br />
actualSize = ...<br />
Prof. Dr.-Ing. G. <strong>Snelting</strong> (Uni Karlsruhe) c○2008 by <strong>IPD</strong> <strong>Snelting</strong> – Programmieren WS 2008/2009 9 / 31
Beispiel 3<br />
<strong>Programmierstil</strong><br />
Namen und Kommentare<br />
Schlecht:<br />
// check if l is bigger than max<br />
if (l > max) {<br />
Gut:<br />
// space left?<br />
if (length > maxLength) {<br />
Prof. Dr.-Ing. G. <strong>Snelting</strong> (Uni Karlsruhe) c○2008 by <strong>IPD</strong> <strong>Snelting</strong> – Programmieren WS 2008/2009 10 / 31
Beispiel 4<br />
Schlecht:<br />
<strong>Programmierstil</strong><br />
Namen und Kommentare<br />
if (first_pointer == begin_of_second) {<br />
// if first list is empty ..<br />
Templist [compare] = Mergelist [second_pointer];<br />
// take element at the second pointer --><br />
// into the Temparray ..<br />
second_pointer++;<br />
// .. and move this pointer to next element.<br />
} //if<br />
Gut:<br />
// if first list is empty, move an element<br />
// from the second list to the temporary.<br />
if (firstPointer == beginOfSecond) {<br />
tempList [compare] = mergeList [secondPointer];<br />
secondPointer++;<br />
}<br />
Prof. Dr.-Ing. G. <strong>Snelting</strong> (Uni Karlsruhe) c○2008 by <strong>IPD</strong> <strong>Snelting</strong> – Programmieren WS 2008/2009 11 / 31
<strong>Programmierstil</strong><br />
Programmlayout<br />
Einrückung<br />
Wird die Programm-Struktur durch konsistente Einrückung und Leerzeilen<br />
verdeutlicht?<br />
Maximale Breite: 80 Zeichen<br />
Eine neue Zeile für jeden Befehl<br />
Absetzen von Strukturen:<br />
Tiefere Einrückung kontrollierter Befehle (konsistent!)<br />
Keine übertriebene Einrückung (2–4 Leerzeichen)<br />
Vor und hinter der Struktur (incl. Kommentar) genau eine Leerzeile.<br />
Strukturierung von Operatoren und Operanden durch Leerzeichen<br />
(konsistent!)<br />
Leerzeilen zwischen Methoden (konsistent!)<br />
Prof. Dr.-Ing. G. <strong>Snelting</strong> (Uni Karlsruhe) c○2008 by <strong>IPD</strong> <strong>Snelting</strong> – Programmieren WS 2008/2009 12 / 31
Beispiel 5<br />
<strong>Programmierstil</strong><br />
Programmlayout<br />
Schlecht:<br />
while(length++
<strong>Programmierstil</strong><br />
Beispiel 5 - Auch schlecht<br />
Programmlayout<br />
while ( length < maxLength )<br />
{<br />
if ( found )<br />
// Leave the method if we have<br />
// found what we searched<br />
{<br />
return;<br />
}<br />
}<br />
else<br />
// Set found to the result of the call<br />
// of the check method<br />
{<br />
found = check ( list [ length ] );<br />
length = length + 1;<br />
}<br />
Prof. Dr.-Ing. G. <strong>Snelting</strong> (Uni Karlsruhe) c○2008 by <strong>IPD</strong> <strong>Snelting</strong> – Programmieren WS 2008/2009 14 / 31
Beispiel 6<br />
<strong>Programmierstil</strong><br />
Programmlayout<br />
if (k-i>1) qsort(a, i, k-1, k-i); //sorts the lower list if<br />
//includes more than 1<br />
//element<br />
if (j-k>1) qsort(a, k+1, j, j-k); //sorts the bigger list<br />
//if includes more than<br />
//pivot + 1 element<br />
Besser:<br />
// sort the left part of the list<br />
if (pivot - left > 1) {<br />
qsort(list, left, pivot - 1, pivot - left);<br />
}<br />
// sort the right part of the list<br />
if (right - pivot > 1) {<br />
qsort(list, pivot + 1, right, right - pivot);<br />
}<br />
Prof. Dr.-Ing. G. <strong>Snelting</strong> (Uni Karlsruhe) c○2008 by <strong>IPD</strong> <strong>Snelting</strong> – Programmieren WS 2008/2009 15 / 31
<strong>Programmierstil</strong><br />
Programmlayout<br />
Überlange Zeilen<br />
Passt ein Ausdruck nicht auf eine Zeile,<br />
muss er umgebrochen werden:<br />
Maximale Breite: 80 Zeichen<br />
Hinter einem Komma, aber vor Operatoren<br />
Trenne die äußerste Struktur<br />
Richte neue Zeile gemäß des umgebenden Ausdrucks aus<br />
Benutze Addition für überlange Zeichenketten<br />
Vermeide verwirrende Einrückungen.<br />
Prof. Dr.-Ing. G. <strong>Snelting</strong> (Uni Karlsruhe) c○2008 by <strong>IPD</strong> <strong>Snelting</strong> – Programmieren WS 2008/2009 16 / 31
Beispiel 7<br />
<strong>Programmierstil</strong><br />
Programmlayout<br />
Schlecht:<br />
longName = longerName + (evenLongerName<br />
+ alsoLongName) + shortName;<br />
if ((condition1 && condition2) ||<br />
(condition3 && condition4)) {<br />
doSomething();<br />
Gut:<br />
longName = longerName<br />
+ (evenLongerName + alsoLongName) + shortName;<br />
if ((condition1 && condition2)<br />
|| (condition3 && condition4)) {<br />
doSomething();<br />
Prof. Dr.-Ing. G. <strong>Snelting</strong> (Uni Karlsruhe) c○2008 by <strong>IPD</strong> <strong>Snelting</strong> – Programmieren WS 2008/2009 17 / 31
<strong>Programmierstil</strong><br />
Programmstruktur und Lokalität<br />
Struktur<br />
Wird das Verfolgen des Programm-Ablaufs durch kleine,<br />
wohlstrukturierte Prozeduren unterstützt?<br />
Grundsatz:<br />
Was immer in eine eigene Methode ausgelagert werden kann,<br />
sollte ausgelagert werden:<br />
Algorithmen<br />
Methoden zur Realisierung einer Funktion aus der Aufgabenstellung<br />
Elementare Operationen auf Datenstrukturen<br />
Mehr als 60 Zeilen in einer Methode?<br />
⇒ Kann man sie aufteilen?<br />
(Wenn nicht, kommentieren Sie dieses Problem.)<br />
Prof. Dr.-Ing. G. <strong>Snelting</strong> (Uni Karlsruhe) c○2008 by <strong>IPD</strong> <strong>Snelting</strong> – Programmieren WS 2008/2009 18 / 31
Beispiel 8 - Schlecht<br />
<strong>Programmierstil</strong><br />
Programmstruktur und Lokalität<br />
switch (ergebnis.command) {<br />
case ’a’: //read name,score<br />
ergebnis.input2 = StdInput.readString();<br />
ergebnis._points_ = StdInput.readInt();<br />
//wrong input exception:<br />
if ((ergebnis._points_ >100) || (ergebnis._points_
Beispiel 8 - Gut<br />
<strong>Programmierstil</strong><br />
Programmstruktur und Lokalität<br />
private void readAddition() {<br />
ergebnis.name = StdInput.readString();<br />
ergebnis.score = StdInput.readInt();<br />
...<br />
}<br />
...<br />
switch (ergebnis.command) {<br />
case ’a’:<br />
// read name and score<br />
readAddition();<br />
break;<br />
Prof. Dr.-Ing. G. <strong>Snelting</strong> (Uni Karlsruhe) c○2008 by <strong>IPD</strong> <strong>Snelting</strong> – Programmieren WS 2008/2009 20 / 31
<strong>Programmierstil</strong><br />
Programmstruktur und Lokalität<br />
Lokalität<br />
Ist jede Komponente so lokal wie möglich gewählt?<br />
Jede Komponente nur verwendbar, wo nötig<br />
Verwendung von Zugriffsmethoden<br />
anstelle direkter Zugriffe auf Variablen fremder Klassen.<br />
(get..., set..., is..., . . . )<br />
Definition lokaler Variablen bei Bedarf, nicht “auf Vorrat”<br />
Prof. Dr.-Ing. G. <strong>Snelting</strong> (Uni Karlsruhe) c○2008 by <strong>IPD</strong> <strong>Snelting</strong> – Programmieren WS 2008/2009 21 / 31
Beispiel 9<br />
Schlecht:<br />
<strong>Programmierstil</strong><br />
Programmstruktur und Lokalität<br />
class Sort {<br />
static int i, j, k; // reserve some variables<br />
public void sort(...) {<br />
...<br />
for (i = 0; i < max; i++) {<br />
k = list[i];<br />
list[i] = list[i + 1];<br />
list[i + 1] = k;<br />
Besser:<br />
class Sort {<br />
public void sort(...) {<br />
...<br />
for (int i = 0; i < max; i++) {<br />
int swap = list[i];<br />
list[i] = list[i + 1];<br />
list[i + 1] = swap;<br />
Prof. Dr.-Ing. G. <strong>Snelting</strong> (Uni Karlsruhe) c○2008 by <strong>IPD</strong> <strong>Snelting</strong> – Programmieren WS 2008/2009 22 / 31
<strong>Programmierstil</strong><br />
Programmstruktur und Lokalität<br />
Anpassbarkeit<br />
Kann das Programm ohne großen Aufwand an veränderte<br />
Randbedingungen angepasst werden?<br />
Verwendung von Konstanten<br />
Benutzung von Zugriffsmethoden anstelle direkter Zugriffe auf<br />
Variablen fremder Klassen<br />
(get..., set..., is..., . . . )<br />
Vermeidung von redundantem Code<br />
Entscheidend: Struktur Ihres Programmes<br />
Prof. Dr.-Ing. G. <strong>Snelting</strong> (Uni Karlsruhe) c○2008 by <strong>IPD</strong> <strong>Snelting</strong> – Programmieren WS 2008/2009 23 / 31
<strong>Programmierstil</strong><br />
Programmstruktur und Lokalität<br />
Konstanten<br />
Wiederkehrende Werte an einer Stelle definiert<br />
public static final double VAT = 0.19;<br />
⇒ Änderungen nur an einer Stelle nötig<br />
Dokumentationswert durch Namen an Verwendungsstelle<br />
public static final double KM IN A MILE = 1.609;<br />
... dist = dist * KM IN A MILE; ...<br />
⇒ Aussagekräftige Namen verwenden!<br />
Prof. Dr.-Ing. G. <strong>Snelting</strong> (Uni Karlsruhe) c○2008 by <strong>IPD</strong> <strong>Snelting</strong> – Programmieren WS 2008/2009 24 / 31
Beispiel 10<br />
<strong>Programmierstil</strong><br />
Programmstruktur und Lokalität<br />
Unschön:<br />
int[] rankings;<br />
int elements;<br />
...<br />
rankings = new int[100];<br />
...<br />
if (elements > 99) {<br />
System.out.println(<br />
"Kein Platz mehr! "<br />
+ "(max. 100)");<br />
Besser:<br />
static final MAX_ELEMENTS = 100;<br />
int[] rankings;<br />
int elements;<br />
...<br />
rankings = new int[MAX_ELEMENTS];<br />
...<br />
if (elements > MAX_ELEMENTS - 1) {<br />
System.out.println(<br />
"Kein Platz mehr! (max. "<br />
+ MAX_ELEMENTS + " Elemente)");<br />
Prof. Dr.-Ing. G. <strong>Snelting</strong> (Uni Karlsruhe) c○2008 by <strong>IPD</strong> <strong>Snelting</strong> – Programmieren WS 2008/2009 25 / 31
Beispiel 11<br />
<strong>Programmierstil</strong> Weitere Beispiele . . .<br />
Schlecht<br />
Gut<br />
if (valid == true) {<br />
return true;<br />
} else {<br />
return false;<br />
}<br />
return valid;<br />
Prof. Dr.-Ing. G. <strong>Snelting</strong> (Uni Karlsruhe) c○2008 by <strong>IPD</strong> <strong>Snelting</strong> – Programmieren WS 2008/2009 26 / 31
Beispiel 12<br />
<strong>Programmierstil</strong> Weitere Beispiele . . .<br />
Schlecht<br />
Gut<br />
if (isFooBar() == false) {<br />
...<br />
}<br />
if (!isFooBar()) {<br />
...<br />
}<br />
Prof. Dr.-Ing. G. <strong>Snelting</strong> (Uni Karlsruhe) c○2008 by <strong>IPD</strong> <strong>Snelting</strong> – Programmieren WS 2008/2009 27 / 31
<strong>Programmierstil</strong><br />
Vergleiche bei float und double<br />
Allgemeine Programmertipps<br />
Vorsicht mit Gleitkommazahlen, besonders bei Vergleichen:<br />
class TestFloat {<br />
}<br />
... main(...) {<br />
foo(1.03, 0.42);<br />
}<br />
void foo(float f1, float f2) {<br />
if (f1 - f2 == 0.61)<br />
println("Got it!");<br />
else<br />
println("Fail");<br />
}<br />
Ergebnis: Fail<br />
1.03 − .42 0.6100000000000001<br />
(Gleitkommafehler)<br />
⇒ == greift nicht!<br />
Gefahr bei Berechnungen:<br />
Aufschaukeln der Gleitkommafehler (→ Numerik)<br />
Lösung: Test auf Epsilon-Umgebung:<br />
if (Math.abs(f1 - f2 - 0.61) < 0.000001) ...<br />
Prof. Dr.-Ing. G. <strong>Snelting</strong> (Uni Karlsruhe) c○2008 by <strong>IPD</strong> <strong>Snelting</strong> – Programmieren WS 2008/2009 28 / 31
<strong>Programmierstil</strong><br />
Allgemeine Programmertipps<br />
Benutzt die Java API!<br />
Vorteile von Standardbibliotheken<br />
Gesparte Arbeit Das Rad nicht immer wieder neu erfinden.<br />
Expertenwissen Bibliotheken werden oft von Experten geschrieben.<br />
Schwer zu schlagen ...<br />
In Java:<br />
Erprobt Standardbibliotheken häufig verwendet<br />
⇒ gut getestet<br />
sehr umfangreiche Standardbibliothek mitgeliefert<br />
regelmäßig erweitert<br />
besonders wichtig:<br />
java.lang<br />
java.util<br />
java.io (zum Teil)<br />
Prof. Dr.-Ing. G. <strong>Snelting</strong> (Uni Karlsruhe) c○2008 by <strong>IPD</strong> <strong>Snelting</strong> – Programmieren WS 2008/2009 29 / 31
<strong>Programmierstil</strong><br />
Allgemeine Programmertipps<br />
Packages und Import<br />
Klasse C in anderem Package p definiert<br />
⇒ mit Import auch in anderem Package verfügbar<br />
Beispiel:<br />
Imports am Dateianfang vor Klassendefinition<br />
import p.C;<br />
Auch import p.* für alle Klassen von p möglich<br />
Nachteile:<br />
mehr Namenskonflikte<br />
Was wird wirklich benötigt?<br />
import java.util.LinkedList;<br />
import java.util.ArrayList;<br />
import java.io.IOException;<br />
Prof. Dr.-Ing. G. <strong>Snelting</strong> (Uni Karlsruhe) c○2008 by <strong>IPD</strong> <strong>Snelting</strong> – Programmieren WS 2008/2009 30 / 31
<strong>Programmierstil</strong><br />
Allgemeine Programmertipps<br />
Allgemeines, in eigener Sache<br />
Sinn der JCC: Über den Sinn einzelner Regeln der JCC kann man sicher<br />
diskutieren. Das wird Ihnen auch später im Berufsleben so gehen,<br />
Firmen verwenden fast immer (eigene) Code Conventions.<br />
Dennoch: Die JCC sind verbindlich für alle vorgegeben, wir<br />
bewerten danach! Sie stehen nicht zur Diskussion.<br />
Die JCC sind auch keine Erfindung von uns, sondern ein<br />
internationaler Standard.<br />
Folien und JCC: Auf den Folien wird öfters Code präsentiert, der nicht<br />
den JCC genügt.<br />
Das ist keine Rechtfertigung, die JCC in Ihren Programmen<br />
nicht einzuhalten. Bei Folien ist im Gegensatz zu<br />
Quellcodedateien der Platz sehr begrenzt.<br />
Prof. Dr.-Ing. G. <strong>Snelting</strong> (Uni Karlsruhe) c○2008 by <strong>IPD</strong> <strong>Snelting</strong> – Programmieren WS 2008/2009 31 / 31