Leitfragen und Übungsaufgaben zum roten Grad des Clean-Code-Developers
https://bildung.social/@oerinformatik/111334923701270625
https://oer-informatik.de/cleancode-rotergrad-uebung
Clean Code, Clean-Code-Developer, Roter Grad, DRY, KISS, FCoI, IOSP, Refactoring, Pfadfinderregel, Root Cause Analysis, Übungsaufgaben, Prüfungsvorbereitung
tl/dr; (ca. 42 min Lese- und Bearbeitungszeit): Leitfragen und Übungsaufgaben zu Clean Code: Der Artikel enthält eine Reihe von Leitfragen zum Verständnis der Prinzipien (DRY, KISS, BoPO, FCoI, IOSP) und Praktiken (Boy Scout, Root Cause, VCS, Refactoring, Reflection), die im roten Grad des Clean-Code-Developers zusammengefasst sind. Am Ende findet sich eine praktische Übungsaufgabe, bei der Clean-Code-Prinzipien angewendet werden sollen [AI-Assisted]. (Zuletzt geändert am 28.10.2026)
Um die Leitfragen beantworten zu können, solltest Du Dich zunächst mit dem roten Grad des Clean Code Developers beschäftigen - oder auf anderem Weg mit den Prinzipien (DRY, KISS, BoPO, FCoI, IOSP) und den Praktiken (Boy Scout, Root Cause, VCS, Refactoring, Reflection) vertraut machen.
Hinweise zur Bearbeitung: Beantworte jede Leitfrage zunächst schriftlich in eigenen Worten und klappe erst dann die Antwort auf. Die Punkte je Frage geben einen Anhaltspunkt für den erwarteten Umfang der Antwort. Die Übungsaufgabe am Ende wendet die Prinzipien auf ein Python-Beispiel an; ihre Beispiellösungen sind ausgeblendet und mit Punkteverteilung versehen.
Was versteht man bei der Programmierung unter Refaktorisierung? (2 Punkte)
Refaktorisieren bedeutet, den Quellcode zu verbessern, ohne die Funktionalität zu verändern. Der Quellcode wird dabei dahingehend geändert, dass er Coding Conventions entspricht, übersichtlicher, lesbarer, wartbarer wird. Er wird mit Kommentaren ergänzt oder von überflüssigen Kommentaren und Codeabschnitten befreit.
Das Designprinzip Don’t repeat yourself (DRY) schlägt vor, dass Redundanzen aus dem Code entfernt werden sollen. Unter welchen Umständen sollten Wiederholungen nicht refaktorisiert werden, also gegen das Prinzip verstoßen werden? (1 Punkt)
Immer dann, wenn andere Design-Prinzipien dadurch verletzt werden, sollte man überprüfen, ob Wiederholungen das geringere Übel sind.
Clean Code kennt das Keep it simple, stupid (KISS)-Prinzip. Welche Praktiken helfen, das KISS-Prinzip einzuhalten? (2 Punkte)
Auf einfache Lösungen kommt man selten allein. Daher sind vor allem Review-Techniken, die hierbei helfen: Pair Programming, Team-Reviews, Rubber-Duck-Review.
Albert Einstein wird ein Zitat zugeschrieben, das das Keep it simple, stupid (KISS)-Prinzip gut beschreibt. Wie lautet es? (1 Punkt)
Alles sollte so einfach wie möglich gemacht werden, aber nicht einfacher.
Auch für Datenstrukturen gilt das KISS-Prinzip. An welches Beispiel kann man das Prinzip erläutern? (2 Punkte)
Bei einfachen Aufzählungen können Datentypen verwendet werden, die genau nur das tun (z.B.
ENUM) anstatt komplexere Strukturen zu verwenden (wie etwa die ObjektsammlungenListoderCollection- Bezeichner natürlich in jeder Sprache anders).Welche Gründe werden angeführt, auf Optimierungen zu verzichten? (1 Punkt)
Auf Optimierungen kann verzichtet werden, wenn:
andere Prinzipien leiden (wie die Verständlichkeit, Fehlerrobustheit,…)
wenn die Optimierung keine Kundenanforderung betrifft
Welche Voraussetzungen müssen vorliegen, damit optimiert werden darf? (1 Punkt)
Optimiert werden sollte nur, wenn durch Messung nachgewiesen wurde, dass die betreffende Stelle tatsächlich der Flaschenhals (oder Problemursache) ist.
Das Favour Composition over Inheritance (FCoI) - Prinzip spricht sich dagegen aus, in jedem Fall Vererbung zur Erweiterung zu nutzen. Welche Probleme entstehen bei der Vererbung, die so verhindert werden sollen? (2 Punkte)
Innerhalb von Vererbungsstrukturen ist der Codetausch zur Laufzeit nicht möglich. Abhängigkeiten der Kindklasse von der Elternklasse können nicht gelöst werden. Die Klassen sind so nicht isoliert testbar. Diese feste Kopplung erhöht die Komplexität. Durch lose Kopplung (per Aggregation/Komposition) können diese Nachteile verhindert werden.
Erkläre, warum die Begriffe whitebox reuse und blackbox reuse im Zusammenhang mit dem FCoI-Prinzip gebraucht werden! (3 Punkte)
Whitebox-Reuse steht für Vererbung. Bei der Vererbung sind die wiederverwendeten Codebestandteile von Beginn an klar und transparent: sie können nicht getauscht werden.
Wird Code über lose Kopplung (Aggregation/Komposition) wiederverwendet, so ist nicht transparent, welcher Code genutzt wird: das Aggregat kann getauscht werden. Man sieht also nicht, welcher Code angefügt wird. Es ist eine Blackbox.
Warum kann man sagen, dass Vererbung die Kapselung zerstört? (4 Punkte)
Bei Vererbung hängt die Kindklasse von Details/Implementierung der Elternklasse ab. Änderungen in der Elternklasse können die Funktionalität der Kindklasse zerstören.
Beispiel: die Elternklasse
Addresshat ein gekapseltes Attributphonenr, das über den Setter oder über den Konstruktor (der den Setter aufruft) gesetzt werden kann. Eine KindklasseInternationalAddressspezialisiert den Setter, um immer in der internationalen Variante+49 ..abzuspeichern. Die Kindklasse geht davon aus, dass die Elternklasse alle neuen Attributwerte über den Setter-Aufruf speichert. Wird dieses Verhalten in der Elternklasse geändert (z.B. indem der Konstruktor direkt das Attribut schreibt), funktioniert die Kapselung des Attributs in der Kindklasse nicht mehr so, wie erwartet. (Fragile base class-Problem)Im Integration Operation Segregation Principle (IOSP) wird von den Nachteilen tiefer Hierarchien (also viele Einrückungsebenen, Blöcken) gesprochen. Was ist so schlecht daran? (3 Punkte)
Bei tiefen Hierarchien, also Code, der mit vielen verschachtelten Codeblöcken auf vielen Ebenen arbeitet, leidet die Lesbarkeit. Die wesentliche und wichtigste Struktur liegt oft auf der unteren Ebene - diese ist dann über viele Codezeilen verteilt. Codeblöcke, die in einer Ebene sind, können nicht auf Anhieb zugeordnet werden. Es kommt so häufig vor, dass z.B.
else-Zweige einem falschenif-Statement zugeordnet werden.In welche Kategorien werden Methoden gemäß IOSP aufgeteilt? (1 Punkt)
Methodenaufrufe, die Abläufe gliedern = Integration
Logik von den Abläufen getrennt: Transformationen, Kontrollstrukturen, I/O = Operation
Welche Größenordnung an Codezeilen wird für Methoden angegeben? (2 Punkte)
Im Text sind 10, 20, 30 Zeilen angegeben. Eine absolute Maximalgröße ist jedoch nicht festlegbar. Richtwerte können im Rahmen der Coding Conventions im Team abgestimmt werden.
Wie helfen mir Methodennamen, das IOS-Prinzip einzuhalten? (2 Punkte)
Findet sich schnell ein Methodenname, der alles beschreibt, was in der Methode passiert, ist das IOSP gewahrt. Neigt man dazu, im Methodennamen ein “UND” einzufügen, ist es entweder eine Integrationsmethode - oder sie sollte weiter aufgeteilt werden.
Als eine Praktik wird die Pfadfinderregel genannt (“Boy Scout Rule”). Wie lautet die Pfadfinderregel im Original? (2 Punkte)
“Always leave the code you are working on a little bit better than you found it.”
Bei den Pfadfindern ist es der Ort (z.B. Zeltplatz), den sie sauberer verlassen sollen, als sie ihn vorgefunden haben.
Was besagt die “Broken Windows Theorie” hinsichtlich Softwareentwicklung? (3 Punkte)
Im Original besagt die Theorie, dass kleine Zerstörungen (z.B. kaputte Fensterscheiben) zur Folge haben, dass auch andere Dinge zerstört werden (am Ende: ganze Stadtviertel). Daher sollte man auch kleine Schäden schnell beheben. In der Softwareentwicklung bedeutet dies, dass kleine Ungenauigkeiten, Abkürzungen oder unsauberer Code dafür sorgen, dass sich andere ermutigt fühlen, das Chaos zu vergrößern. Daher sollte man immer für aufgeräumten, sauberen Code sorgen.
Warum löst es nicht nur das Problem nicht, sondern ist auch gefährlich, das Symptom zu bearbeiten und nicht den Root Cause? (2 Punkte)
Durch Symptombekämpfung werden Fehler versteckt. Gegebenenfalls treten sie erst wieder zutage, wenn es fatale Auswirkungen hat. Da das eigentliche Problem nicht mehr offensichtlich ist, verbleibt es wie eine tickende Zeitbombe im System.
Welche einfachen Refaktorisierungsmuster gibt es, die man von Beginn an (auch als Berufsanfänger) beherzigen kann und sollte? (1 Punkt)
Methoden extrahieren
Umbenennen
Welche Techniken helfen, Reflexionen im Alltag einzuplanen? (2 Punkte)
Kleinschrittige Planung
Reflexion nach jedem Schritt
Abends / kurz vor Feierabend: Habe ich alle meine Aufgaben erledigt? Wie habe ich meine Aufgaben erledigt?
Übungsaufgabe Clean Code
Um die benötigte Heizwärme unterschiedlicher Jahre vergleichen zu können, werden die Abnahmemengen des bezogenen Energieträgers klimabereinigt. Dazu wird die Heizenergie über die Außentemperatur normiert. Es wird davon ausgegangen, dass Heizungen nur bei Außentemperaturen unterhalb einer “Heizgrenztemperatur” (hier beispielhaft heizgrenze=14\rm{^{\circ}C}) aktiviert sind. (Tage, bei denen das zutrifft, sind in der Tabelle mit TRUE in der Spalte “Heiztag” markiert).
Unterhalb der Heizgrenztemperatur steigt der Heizbedarf proportional zur Temperaturdifferenz aus der jeweiligen Außentemperatur (tm \_temp[i]) und einer angesetzten Raumtemperatur (z.B. raumtemp=18\rm{^{\circ}C}). Daher werden zur Normierung diese Temperatursummen für alle Tage addiert, an denen die Heizgrenztemperatur unterschritten wird.
Gradtagszahl=\sum_{i=0}^{anzahl\_tage-1}{(raumtemp - tm \_temp[i])\ if\ (tm \_temp[i] < heizgrenze)\ else\ 0}
Die Werte können beispielsweise so aussehen:
| Index | Datum | Tagesmittel der Außentemperatur in ^{\circ}C |
Gasbedarf in kWh |
Heiztag | Gradtagszahl in ^{\circ}C |
|---|---|---|---|---|---|
| tag | datum | tm \_temp[i] | gasverbrauch | ||
| 2920 | 12.09.2022 | 16,1 | 2,946 | FALSE |
0,0 |
| 2921 | 13.09.2022 | 18,3 | 3,160 | FALSE |
0,0 |
| 2922 | 14.09.2022 | 13,4 | 19,704 | TRUE |
4,6 |
| 2923 | 15.09.2022 | 14,2 | 2,89 | FALSE |
0,0 |
| 2924 | 16.09.2022 | 12,6 | 22,429 | TRUE |
5,4 |
| 2925 | 17.09.2022 | 11,2 | 28,011 | TRUE |
6,8 |
| 2926 | 18.09.2022 | 10,2 | 31,425 | TRUE |
7,8 |
Die folgende Python-Funktion berechnet die Heizkennziffer vereinfacht mit folgender Formel:
Heizkennziffer=\frac{\sum{Gasbedarf}}{Gradtagszahl}
Folgender Quellcode liegt dafür bislang vor:
def heizkennziffer(gesamt_gasverbrauch, gesamt_temp_profil,
start_tag, tage_anzahl, raumtemp, heizgrenze):
gasverbrauch = gesamt_gasverbrauch[start_tag:start_tag+tage_anzahl]
temp_profil = gesamt_temp_profil[start_tag:start_tag+tage_anzahl]
g = 0 # Gradtagszahl
for tagesmittel_temp in temp_profil:
if tagesmittel_temp < heizgrenze:
g += raumtemp - tagesmittel_temp
v = 0 # Gasverbrauch
for tagesverbrauch in gasverbrauch:
v += tagesverbrauch
if (g>0):
kennziffer = v/g
else:
kennziffer = 999
return kennzifferDer vorige Codeausschnitt wurde noch nicht mithilfe von Clean-Code Prinzipien und Praktiken refaktorisiert.
Was versteht man unter Refaktorisierung? Nenne eine Definition sowie zwei einfache Refaktorisierungsmuster. (3 Punkte)
Refaktorisieren heißt, die innere Struktur des Quellcodes zu verbessern (lesbarer, verständlicher, wartbarer), ohne sein von außen beobachtbares Verhalten zu verändern. Tests vor und nach der Änderung sichern ab, dass das Verhalten gleich bleibt. (1 P.)
Einfache Refaktorisierungsmuster (je 1 P., zwei genügen):
Methode extrahieren (Extract Method): einen zusammengehörigen Codeabschnitt in eine eigene, sprechend benannte Funktion auslagern, z. B. die Berechnung der Gradtagszahl.
Umbenennen (Rename): nichtssagende Bezeichner durch sprechende ersetzen, z. B.
g→gradtage,v→verbrauch.Magische Zahl durch Konstante ersetzen: z. B.
999→KEIN_HEIZTAG.
Welche Änderungen kannst Du bei dem dargestellten Quellcode anwenden, damit das IOSP-Prinzip umgesetzt wird? Nenne in einem Satz zwei Änderungen, die Du hierfür vornehmen würdest (Du kannst auch oben im Quellcode Hinweise eintragen). (4 Punkte)
Die Funktion
heizkennziffer()mischt bislang Integration (den Gesamtablauf) und Operationen (Schleifen, Bedingungen, Rechnungen). Nach IOSP würde ich die Berechnung der Gradtagszahl und die Summierung des Gasverbrauchs (sowie die Division mit Sonderfall) in eigene Operations-Funktionen auslagern, sodassheizkennziffer()nur noch diese Funktionen aufruft und selbst keine Logik mehr enthält. (je Änderung 2 P.: 1 P. für die Änderung, 1 P. für den Bezug zu Integration bzw. Operation)Eine mögliche Umsetzung (die Ergebnisse sind für alle Eingaben gleich wie beim Ausgangscode, für die Tabellenwerte z. B. Gradtagszahl 24,6 und Heizkennziffer ca. 4,49):
KEIN_HEIZTAG = 999 # Rückgabewert, wenn im Zeitraum kein Heiztag liegt def heizkennziffer(gesamt_gasverbrauch, gesamt_temp_profil, start_tag, tage_anzahl, raumtemp, heizgrenze): """Integration: ruft nur andere Funktionen auf, enthält selbst keine Logik.""" gasverbrauch = zeitraum(gesamt_gasverbrauch, start_tag, tage_anzahl) temp_profil = zeitraum(gesamt_temp_profil, start_tag, tage_anzahl) return kennziffer(summe_verbrauch(gasverbrauch), gradtagszahl(temp_profil, raumtemp, heizgrenze)) def zeitraum(werte, start_tag, tage_anzahl): return werte[start_tag:start_tag + tage_anzahl] def gradtagszahl(temp_profil, raumtemp, heizgrenze): return sum(raumtemp - temp for temp in temp_profil if temp < heizgrenze) def summe_verbrauch(gasverbrauch): return sum(gasverbrauch) def kennziffer(verbrauch, gradtage): if gradtage > 0: return verbrauch / gradtage return KEIN_HEIZTAGIm obigen Codeausschnitt wird zweimal eine Schleife über alle beobachteten Tage durchlaufen, was sich zusammenfassen lässt. Erkläre in einem Satz hinsichtlich des “Beware of Premature Optimization”-Prinzips, warum es sinnvoll sein kann, diese Zusammenfassung nicht vorzunehmen! (2 Punkte)
Eine zusammengefasste Schleife spart bei wenigen hundert Tageswerten kaum messbare Laufzeit, vermischt aber zwei Aufgaben (Gradtagszahl und Gasverbrauch) in einem Block, wodurch der Code schwerer lesbar, testbar und nach IOSP aufteilbar wird; optimiert werden sollte erst, wenn eine Messung zeigt, dass diese Stelle tatsächlich ein Flaschenhals ist. (1 P. geringer Nutzen ohne Messung, 1 P. Nachteil für Lesbarkeit bzw. Trennung der Belange)
Links und weitere Informationen
Hinweis zur Nachnutzung als Open Educational Resource (OER)
Dieser Artikel und seine Texte, Bilder, Grafiken, Code und sonstiger Inhalt sind - sofern nicht anders angegeben - lizenziert unter CC BY 4.0. Nennung gemäß TULLU-Regel bitte wie folgt: “Leitfragen und Übungsaufgaben zum roten Grad des Clean-Code-Developers” von oer-informatik.de (H. Stein), Lizenz: CC BY 4.0. Der Artikel wurde unter https://oer-informatik.de/cleancode-rotergrad-uebung veröffentlicht, die Quelltexte sind in weiterverarbeitbarer Form verfügbar im Repository unter https://gitlab.com/oer-informatik/design-prinzipien/clean-code. Erstellt mit KI-Assistenz; von mir umfassend redaktionell überarbeitet, geprüft und freigegeben. Stand: 28.10.2026.
[Kommentare zum Artikel lesen, schreiben] / [Artikel teilen] / [gitlab-Issue zum Artikel schreiben]
