Goldene Regeln zur Programmentwicklung


Halten Sie die Bezeichner-Konventionen ein

Um eine durchgängige Bezeichnung von Klassen, Attributen und Operationen zu erreichen, gibt es einige Konventionen zu beachten:

  • Bezeichner werden in Form der "Smalltalk-Notation" gewählt: Innerhalb eines Bezeichners werden Worte nur durch Großbuchstaben abgesetzt, also "pruefeWert" und nicht "pruefewert" oder "pruefe_wert" (Camel case). Unterstriche und andere Trenner sind nicht konventionsgemäß.
     
  • Bezeichner für Klassennamen beginnen mit einem Großbuchstaben. Und sie sind stets im Singular formuliert.
     
  • Bezeichner für Konstanten werden insgesamt in Großbuchstaben geschrieben.
     
  • Bezeichner für Instanzattribute, lokale Attribute und Operationsparameter beginnen mit einem Kleinbuchstaben.
     
  • Bezeichner für Operationen beginnen mit einem Kleinbuchstaben. Das erste Wort einer Operation ist immer ein Prädikat.
     
  • Bezeichner werden in englisch (bevorzugt) oder deutsch formuliert. Und durchgehend in einer einzigen dieser beiden Sprachen.

Beispiel:

class MeineKlasse { // Klassenname
  private final int MAXIMAL = 10; // Konstante
  private String[] zeichenkette = new String[MAXIMAL]; // Instanzattribut
  public String[] gibZeichenkette() { return zeichenkette; } // Operation
}

Fügen Sie Leerzeilen zur Absatzmarkierung ein

Beispiel:

// Einzeldaten sortieren
Arrays.sort(einzeldaten);

---- Absatz ----

// Ausgabe von Operation erstellen lassen und in String-Array speichern.
// Die Operation benötigt die berechneten Statistikwerte als Parameter.
String[] ausgabe = erstelleAusgabe(modus, median, mittel, gesamtmittel);

---- Absatz ----

// Ausgabe-Array mit Schleife auf Konsole ausgeben
System.out.println();
for (int i=0;i<ausgabe.length;i++)
...

Verwenden Sie die Tab-Taste, um Einrückungen innerhalb eines Blockes vorzunehmen

Beispiel:

public void readEinzeldaten() {
--tab--System.out.println(); // Leerzeile ausgeben
--tab--boolean weiter = true;

--tab--do { // while (weiter) -- Solange fragen, bis [Enter] gedrückt.
--tab-- --tab--boolean fehler = false;

--tab-- --tab--do { // while (fehler) -- Bei Fehler, Eingabe wiederholen.
--tab-- --tab-- --tab--System.out.print("Wert Nr. "+(einzeldaten.length+1)+" eingeben: ");

--tab-- --tab-- --tab--// Wert einlesen und umwandeln, falls nicht leer
--tab-- --tab-- --tab--try {
--tab-- --tab-- --tab-- --tab--fehler=false;
--tab-- --tab-- --tab-- --tab--String wertString=reader.readLine(); // Eingabe speichern

Setzen Sie öffnende und schließende Blockklammern untereinander

Beispiel:

do {
|schleifenEnde = true;
|eingabeString = Help.eingabe("\nBitte auswaehlen (1/2/3/4): ");
|eingabeInt = WichtigeMethoden.parseToInteger(eingabeString);
|if((eingabeInt != -1) || (eingabeString.equals("-1"))) {
||try {
|||Help.checkLimit(1, 4, eingabeInt);
||}
||catch (Fehleingabe exp) {
|||schleifenEnde = false;
||}
|}
|else {
||schleifenEnde = false;
|}
} while (schleifenEnde == false);

Wählen Sie sprechende Bezeichner

Beispiel:

double modalWert[][];
double median;
int fahrenheit;
double anfangskapital;

Deklarieren Sie Instanzattribute private und nicht public

Beispiel:

class MeineKlasse { // Klassenname
 public final int MAX = 10; // Konstante
 public String[] zeichenkette = new String[MAX]; // Instanzattribut
 public String[] getZeichenkette() { return zeichenkette; } // Operation
}

Vermeiden Sie Code-Wiederholungen

Sobald Sie feststellen, dass sich Code wiederholt (Redundanz), überlegen Sie, ihn in Operationen auszulagern. Im Beispiel unten sind es die blauen Zeilen, die in eine Operation ausgelagert werden sollten.

if(tabs[i].length() == 1) {
 if(name.startsWith(tabs[i])) {
  jliste[i] = new JList(dataModel[i]);
  jliste[i].setLayoutOrientation(JList.VERTICAL);
  jliste[i].setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL);
  jliste[i].setVisibleRowCount(-1);
  JScrollPane scrollPane = new JScrollPane(jliste[i]);
  scrollPane.setPreferredSize(new Dimension(450, 260));
 }
} else if(tabs[i].length() > 1) {
 String[] subString = new String[tabs[i].length()];
 for(int j = 0; j < subString.length; j++) {
  subString[j] = tabs[i].substring(j, j+1);
  if(name.startsWith(subString[j])) {
   jliste[i] = new JList(dataModel[i]);
   jliste[i].setLayoutOrientation(JList.VERTICAL);
   jliste[i].setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL);
   jliste[i].setVisibleRowCount(-1);
   JScrollPane scrollPane = new JScrollPane(jliste[i]);
   scrollPane.setPreferredSize(new Dimension(450, 260));
  }
 }
}

Dokumentieren Sie Ihr Programm

Für Java gibt es einen ganz eigenen Stil der Dokumentation, für den es im JDK ein eigenes Dokumentationswerkzeug javadoc gibt. Erkannt werden alle Kommentare, die mit /** beginnen und mit */ beendet werden. Zudem gibt es Schlüsselwörter mit spezieller Bedeutung, dazu gehören:

@param - Parameterbeschreibung einer Methode.
@return - Beschreibung des Rückgabewertes einer Operation.
@exception - Beschreibung einer Ausnahme, die von dieser Operationausgelöst wird.
@author - Erzeugt einen Autoreneintrag.
@version - Erzeugt einen Versionseintrag. Darf höchstens einmal je Klasse bzw. Interface verwendet werden.
@since - Beschreibt, seit wann das beschriebene Feature existiert.
@see - Erzeugt einen Querverweis.
@deprecated - Markiert eine veralterte Operation, die zukünftig nicht mehr verwendet werden sollte.

Grundsätzlich sollte jede Operation dokumentiert werden. Dazu gehört insbesondere, dass die Parameter und der Rückgabewert beschrieben werden. Der java-Code selbst sollte lesbar bleiben. Deshalb nicht zuviel Kommentare zwischen den Zeilen, und schon gar nicht jede Zeile einzeln dokumentieren. Kommentarzeilen im Code bei schwierigen Algorithmen sind trotzdem sehr hilfreich.

Beispiel:

/** Konstruktor mit Parametern
  * --------------------------

  * Parameter
  * @param values (double[]): Array mit Messdaten
  * @param extCount (int) : Anzahl zusätzlicher Messdaten
  * @param extAritMittel (double) : arithm. Mittel einer zusätzlichen Messung
  * -----------------------
  * Das Array values wird kopiert und sortiert.
  */

public Statistik(double[] values, int extCount, double extAritMittel) {
 this.values = (double[])values.clone();
 this.extAritMittel = extAritMittel;
 this.extCount = extCount;
 Arrays.sort(this.values);
} // end of constructor

Beispiel:

/** getArrayString
  * ----------------------------
  * @param values (double[]): Array mit Messdaten
  * @param delimiter (String): Trennzeichen
  * @param errorText (String): Fehlertext
  * ------------------------------------------
  * @return gibt String aus zusammengesetzen Arraywerten zurück
  * diese werden einzeln mit dem String delimiter getrennt
  * falls values leer ist oder die Länge 0 hat wird errorText zurückgegeben
  * ------------------------------------------
  * Hilfsoperation zur Ausgabe von Arrays
  */

public String getArrayString(double[] values, String delimiter, String errorText) { ... }

Entwerfen Sie Klassen nicht zu groß, aber auch nicht zu klein

Achten Sie auf Entkopplung von Zuständigkeiten.
Fassen Sie das zu einer Operation zusammen, was sinngemäß zusammengehört - nicht mehr.
Achten Sie auf Entkopplung von Zuständigkeiten.