22.11.2013 Aufrufe

Programmierstil - IPD Snelting

Programmierstil - IPD Snelting

Programmierstil - IPD Snelting

MEHR ANZEIGEN
WENIGER ANZEIGEN

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

Hurra! Ihre Datei wurde hochgeladen und ist bereit für die Veröffentlichung.

Erfolgreich gespeichert!

Leider ist etwas schief gelaufen!