Schwieriger Code
🚧 | Diese Seite befindet sich in Bearbeitung | 🚧 |
🤓 | Diese Seite ist eine Bewertungsrichtlinie, die ab Blatt 1 annotiert und ab Blatt 2 abgezogen wird. | 🤓 |
Beschreibung
Stellen im Quellcode, die komplex oder schwer verständlich sind, sollten mit einem Kommentar versehen werden. Als schwierige Codestellen bezeichnen wir unter anderem die Stellen, die nicht schnell verständlich sind. Falls möglich, sollten komplexe Codestellen in Hilfsmethoden aufgeteilt werden.
Negativbeispiel
public void endGame(int[] numbers, Player player) {
int size = numbers.length;
for (int i = 0; i < size - 1; i++) {
int minimumIndex = i;
for (int j = i + 1; j < size; j++) {
if (numbers[j] < numbers[minimumIndex]) {
minimumIndex = j;
}
}
int temp = numbers[minimumIndex];
numbers[minimumIndex] = numbers[j];
numbers[j] = temp;
}
int sum = 0;
String result = "";
for (Integer number : numbers) {
number += sum;
result += number + " ";
}
System.out.println(result);
System.out.println("Player " + player.getName() + " scored: " + sum);
}
Hier ist nicht genau klar, was im ersten Teil des Codes passiert. Statt der lesenden Person es zu überlassen, den Code im Detail durchzulesen und verstehen zu lassen, wäre es hilfreicher, einen Kommentar zu verfassen oder einen Teil des Codes in eine Hilfsmethode umzulagern.
Ein weiteres Beispiel Quake 3, Inverse-Square-Root-Algorithmus, zwar in der Sprache C, aber trotzdem ein gutes Beispiel:
/**
* Q_rsqrt "Quick-inverse-square-root" calculates the inverse square-root of a given number.
* param number The number to calculate the square-root of
* return float The square-root of the given number
*/
float Q_rsqrt( float number ) {
long i;
float x2, y;
const float threehalfs = 1.5F;
x2 = number * 0.5F;
y = number;
i = * ( long * ) &y; // evil floating point bit level hacking
i = 0x5f3759df - ( i >> 1 ); // what the fuck?
y = * ( float * ) &i;
y = y * ( threehalfs - ( x2 * y * y ) ); // 1st iteration
//y = y * ( threehalfs - ( x2 * y * y ) ); // 2nd iteration, this can be removed
return y;
}
Die Kommentare in dem gegebenen Code machen die Stelle nicht einfacher zu verstehen. Die Stelle ist aus offensichtlichen Gründen sehr komplex und schwer zu verstehen.
Positivbeispiel
public void endGame(int[] numbers, Player player) {
int[] sortedNumbers = selectionSort(numbers);
int sum = 0;
String result = "";
for (Integer number : sortedNumbers) {
number += sum;
result += number + " ";
}
System.out.println(result);
System.out.println("Player " + player.getName() + " scored: " + sum);
}
// The standard selectionsort algorithm.
private int[] selectionSort(int[] unsortedNumbers) {
int[] numbers = unsortedNumbers;
int size = numbers.length;
for (int i = 0; i < size - 1; i++) {
int minimumIndex = i;
for (int j = i + 1; j < size; j++) {
if (numbers[j] < numbers[minimumIndex]) {
minimumIndex = j;
}
}
int temp = numbers[minimumIndex];
numbers[minimumIndex] = numbers[j];
numbers[j] = temp;
}
return numbers;
}
Hier wird durch das erstellen der Hilfsmethode und einem deutenden Kommentar, das lesen und verstehen des Codes vereinfacht. Später im Semester (z.B. Abschlussaufgaben) sollte natürlich kein Sortieralgorithmus selber implementiert werden, sonder auf bestehende Bibliotheksfunktionen zurückgegriffen werden.
Quake-3-Algorithmus, aber verständlicher:
/**
* Q_rsqrt "Quick-inverse-square-root" calculates the inverse square-root of a given number.
* param number The number to calculate the square-root of
* return float The square-root of the given number
*/
float Q_rsqrt( float number ) {
long i;
float x2, y;
const float threehalfs = 1.5F;
x2 = number * 0.5F;
y = number;
i = * ( long * ) &y; // Converting the adress from a float which is tied to the IEEE-754 standard to a long which allows "proper" bit-magic
i = 0x5f3759df - ( i >> 1 ); // This will result in a good approximation. The magic number improves accuracy of the approximation by giving it the least average differentiation from the real value
y = * ( float * ) &i;
y = y * ( threehalfs - ( x2 * y * y ) ); // first iteration of approximating with the newton method
return y;
}
Aus offensichtlichen Gründen ist dieser Code besser dokumentiert und einfacher zu verstehen.
Weitere Beispiele für schwieriger Code
// If the regular expression is not trivial, like in the code below, one should explain it in a comment before the regex.
public class Main {
private static final String REGEX_MATCH_NON_PRIME = ".?|(..+?)\\1+";
public static void main(String[] args) {
int inputNumber = Integer.parseInt(args[0]);
System.out.println(isPrime(inputNumber));
}
public static boolean isPrime(int n) {
return !new String(new char[n]).matches(REGEX_MATCH_NON_PRIME);
}
}