Leitfragen und Übungsaufgaben zum orangen Grad des Clean-Code-Developers

https://bildung.social/@oerinformatik/111334923701270625

https://oer-informatik.de/cleancode-oranger-grad-uebung

tl/dr; (ca. 30 min Bearbeitungszeit): Leitfragen und Übungsaufgaben zu CleanCode: Der Artikel enthält eine Reihe von Leitfragen zum Verständnis der Prinzipien (SLA, SRP, SoC, Source Code Conventions) und Praktiken (Issue Tracking, Integrationstest, Lesen, Reviews), die im orangenen Grad des Clean-Code-Developers zusammengefasst sind. (Zuletzt geändert am 07.11.2023)

Um die Leitfragen beantworten zu können, solltest Du Dich zunächst mit dem orangenen Grad des Clean Code Developers beschäftigen - oder auf anderem Weg mit den Prinzipien (SLA, SRP, SoC, Source Code Conventions) und den Praktiken (Issue Tracking, Integrationstest, Lesen, Reviews) vertraut machen.

Dall-E hat einen Programmierer mit orangenem Gürtel vor’m PC gezeichnet (nach Gustav Klimmt)

Leitfragen zum orangen Grad

  1. Was wird unter Abstraction im Sinne des Single Layer of Abstraction-Prinzips (SLA) verstanden?

    Abstrahieren beschreibt in der Informatik die Vereinfachung von komplexen Zusammenhängen, eine Reduktion auf die wesentlichen Eigenschaften.

    In diesem Fall ist nicht die Abstraktion im Sinne der Objektorientierten Programmierung (OOP) gemeint (nicht instanziierbare Interfaces und abstrakte Klassen statt konkreter Klassen), sondern die Ebene (oder der Detaillierungsgrad), auf der das Problem im jeweiligen Modul gelöst wird.

    Programmkomponenten, die eine grobe Einteilung des Programms in Schichten umsetzen, befinden sich auf einer komplett anderen Abstraktionsebene als Programmteile, die einzelne Bits in Datenbanken setzen. In der großen Übersicht befinden wir uns auf einem sehr hohen Abstraktionsniveau (es wird viel vereinfacht), in kleinen Programmbestandteilen sind die Zusammenhänge viel näher an dem jeweiligen Ausgangsproblem und es wird deutlich weniger vereinfacht.

    Vergleichsweise einfache Operationen, die ggf. direkt auf der Hardware laufen stellen in der Softwareprogrammierung das niedrigste Abstraktionsniveau dar. Die Schichten, die darauf aufbauen, um komplexere Aufgaben zu lösen, stehen somit auf höheren Abstraktionsebenen.

  2. Welche Folgen hat das Single Layer of Abstraction-Prinzip für die Gliederung / den Aufbau von Klassen?

    Öffentliche Methoden hohen Abstraktionsniveaus sollten im Quelltest oberhalb stehen. Die von ihnen direkt aufgerufenen Methoden (niedrigeren Abstraktionsniveaus) sollten dann folgen uns so weiter.

    So ist eine Klasse von oben nach unten lesbar und jede/r Leser/in kann selbst entscheiden, bis zu welchem Detailgrad (hohes Detailgrad = niedrige Abstraktion) gelesen werden soll.

  3. Nenne Beispiele für unterschiedliche Abstraktionslevel im Sinne des Single Layer of Abstraction-Prinzips.

    Methodenaufruf des Frameworks, Methodenaufruf der JavaAPI, Methodenaufruf der Anwendung.

    Sehr niedriges Abstraktionsniveau: Methode, die nur Grundfunktionen der Programmiersprache nutzt.

    Sehr hohes Abstraktionsniveau: Methode, die auf spezialisierte Klassen eines Frameworks zugreift (und somit auf viele Abstraktionsschichten aufbaut).

  4. Was versteht man unter einer “Verantwortlichkeit” (Responsibility) im Sinne des Single Responsibility Principles (SRP)?

    Verantwortlichkeiten sind die Ziele und Ergebnisse einer Klasse/Methode. Die Verantwortlichkeiten unterschiedlicher Klassen/Methoden können sehr ähnlich sein (z.B. Berechnung von Steuern, Berechnung von Abgaben).

    Programmteile (Klassen, Methoden) haben die Verantwortlichkeit, kleine, isolierte und konkrete Teilprobleme des Softwaresystems zu lösen.

  5. Was versteht man unter einem “Belang” (Concern) im Sinne des SoC?

    Concerns sind Übermengen von Responsibilities: beispielsweise wird der Concern einer Hauptfunktionalität eines Programms (Anforderung) durch mehrere Klassen und Methoden umgesetzt.

    Sie stehen für komplett verschiedene Zwecke, sind also orthogonal zueinander (überschneidungsfrei in den Funktionalitäten).

    Innerhalb einer Codeeinheit sollten Concerns getrennt werden (in Codeblöcke (bzw. Exception, Logging), Methoden, Klassen).

  6. Wie unterscheidet sich eine Verantwortlichkeit (im Sinne des Single Responsibility Principles) von einem Belang (im Sinne des Separation of Concerns)?

    Belange haben eine übergeordnete Funktion, sie beschreiben abstrakte, allgemeine Aufgaben. Diese abstrakten Aufgaben werden an unterschiedlichen Stellen durch mehrere Klassen/Methoden umgesetzt.

    Im Gegensatz zu Verantwortlichkeiten (Responsibilities) gibt es im Idealfall keine Funktionsüberschneidungen bei mehreren Belangen (sie sind orthogonal).

    Verantwortlichkeiten (Responsibilities) lösen kleinere isolierte Probleme und werden auf Ebene einer Klasse oder Methode realisiert.

    Ein Belang kann durch mehrere Verantwortlichkeiten in unterschiedlichen Klassen umgesetzt werden.

    Beispiel: Die Datenpersistenz (Speicherung von Daten, als abstrakte Idee) ist ein Belang. Sie wird durch viele Klassen und Frameworks umgesetzt. Das Speichern eine Adresse (konkrete Klasse) ist aber die Verantwortlichkeit einer einzelnen Klasse (z.B. des AdressModell).

  7. Nenne Beispiele für Verantwortlichkeiten und Belange eines aktuellen Projekts, an dem Du arbeitest!

    • Belang (Concern): z.B. Datenpersistenz, Protokollierung, Exception-Handling, Darstellung, Caching, Busineslogic, Transaktionen

    • Verantwortlichkeit (Responsibility): Speicherung einer spezifischen Entität, Berechnung eines spezifischen Steuersatzes, Validierung eines spezifischen Werts.

  8. In welchen Kontexten sind Coding Conventions wie z.B. Namensregeln, die Attribute von lokalen Variablen unterscheidet, wichtiger, in welchen Kontexten weniger wichtig?

    Coding Conventions sind insbesondere in großen Projekten mit vielen Mitwirkenden, in großen Klassen oder bei fehlender Unterstützung durch die IDE wichtig.

    Sie müssen v.a. auch eingehalten werden, wenn im Rahmen des Software-Deployments auch über Linter die Einhaltung bestimmter Conventionen geprüft wird (z.B. bei Python über PEP8).

  9. Nenne Beispiele für Namensregeln (Coding Conventions) für Attribute und lokale Variablen!

    Attribut: this.name

    lokale Variable: _name, myName

  10. Welche weiteren Namensregeln oder Coding Conventions kennst Du?

    z.B. Java/C++: Klassen groß, Rest klein; Konstanten GROSS

    Python: siehe PEP8, z.B. : zwei Leerzeilen vor neuer Funktion, Dunder (doppelter Unterstrich) für private Attribute…

  11. Als Beispiel für CodingConventions sei die mittlerweile veraltete ungarische Notation genannt: Hierbei geben vorangestellte Prefixe Auskunft über den Datentyp einer Variablen (z.B. strName, intAnzahl, txtEingabefeld, iZahl, checkboxIstWahr). Welche Vorteile / Nachteile bietet die Code-Convention, Variablen mit ungarischer Notation zu nutzen?

    Nachteile: Probleme bei sich ändernden Datentypen, unnötig bei IDE mit Typisierungsunterstützung, Redundante Information (Datentyp in typsicheren Sprachen in Deklaration bereits genannt).

    Vorteile: Nach wie vor üblich in einigen Programmierumgebungen, ggf. hilfreich bei fehlender IDE-Unterstützung für Datentypen.

    (Ungarische Notation ist eine veraltete Coding Convention, an der man gut erkennen kann, dass Konventionen sich über die Zeit ändern können.)

  12. Warum kann das Refaktorisierungsmuster Extract Method helfen, den Code von (unnötigen) Kommentaren zu befreien?

    Werden Codezeilen in Methode ausgegliedert sollte der Methodenname erklären, was die Coderzeilen tun: ein Kommentar ist dadurch unnötig)

    Dall-E hat einen Programmierer mit orangenem Gürtel vor’m PC gezeichnet (nach Gustav Klimmt)
  13. Was sollte in Kommentaren genannt werden, und was nicht?

    Kommentiert werden sollte nicht was man tut, sondern wieso man etwas tut und auch wieso man etwas anderes nicht tut (verworfene Alternativen mit Begründung).

    Da Kommentare schlecht altern (häufig nicht mit Codeänderungen gepflegt werden) sollten v.a. Dinge kommentiert werden, die auch nach Codeanpassungen noch relevant sind. Redundanzen sollten vermieden werden.

    In Kommentaren kann außerdem stehen, was man im Code selbst nicht mehr sieht: warum habe ich eine Alternative verworfen? Welche Alternativen hatte ich erwogen? Diese Art Kommentar hilft, damit das zukünftige ich (oder andere Entwickler*innen) nicht dasselbe Problem ein zweites Mal auf Irrwegen versuchen zu lösen.

  14. Welche Möglichkeiten gibt es, offene Arbeitspakete zu dokumentieren?

    Beispielsweise:

    • ToDo-Liste

    • Issue Tracker

    • Taskboard

  15. Welche Möglichkeiten über das reine Sammeln hinaus ergeben sich durch Issue-Tracking?

    Issue-Tracking hilft beispielsweise auch dabei, die spontan auftretende Arbeit

    • zu priorisieren,

    • zu ordnen,

    • Bearbeiter*innen zuordnen,

    • im Prozess nachzuverfolgen,

    • zu dokumentieren und

    • die Anzahl bzw. den Grad der erledigten Arbeit visualisierbar zu machen (Velocity).

  16. Warum werden zunächst Integrationstests beschrieben und nicht Unit-Tests?

    Integrationstests können geschrieben werden, ohne die Abhängigkeiten der Module untereinander zu lösen. Somit können sie schneller erstellt werden und benötigen in einfachster Form auch weniger Fachwissen des Testframeworks. Das gesamte Konzept Stubbing / Mocking muss beispielsweise für Integrationstests nicht vorhanden sein.

    Außerdem benötigt es häufig weniger Integrationstests, um einen größeren Anteil an Code mit den Tests zu erreichen, da diese einen Stich durch alle Schichten des Programms testen.

  17. Warum lohnt es sich, mit hohem Zeitaufwand Tests zu automatisieren?

    Durch automatisierte Tests werden die Tests nur einmal erstellt und können immer wieder (ohne großen Zeitaufwand) aufgerufen werden. Durch die Zeitersparnis bei der Testausführung selbst werden die Tests häufiger ausgeführt, auch bei kleineren Änderungen. Dadurch werden Fehler schneller erkannt. Digitale Schulden und teure späte Fehlererkennung werden so vermieden. Die (relativ billige) Zeit, die zu Beginn eines Arbeitspakets in Tests investiert wird verhindert (relativ teure) Zeitaufwendungen gegen Ende des Entwicklungszyklus.

  18. Warum sind automatische Tests insbesondere dann wichtig, wenn wir - durch unsere Clean-Code-Vorgaben - häufig und viel Refaktorisieren?

    Bei jeder Änderung und bei jedem Refaktorieren kann sich das Team sicher sein, dass die Software noch so funktioniert, wie ursprünglich geplant. Wir verlieren die Angst vor Änderungen. Mit der Sicherheit einer guten Testsuite im Rücken können gefahrloser Refaktorierungen vorgenommen werden: der Code bleibt easy to change (ETC).

  19. Welche Vorteile bieten in Zeiten digitaler Medien Bücher?

    Fachbücher behandeln ein Thema in (meist) vorgegebener Reihenfolge, sie sind ablenkungsfrei und standordunabhängig zu lesen (Park, Öffis). In Büchern kann einfach annotiert (Textmarker) und kommentiert (Lesezeichen, PostIt, Seitenrand) werden. Bücher werden häufig noch aufwändiger redigiert, viele Fachbücher behandeln nicht kurzfristige Trends sondern allgemeine Grundsätze, die Zeiten überdauern. Einige Bücher gehen in den Kanon der Standardwerke ein und geben die Sprache vor, die zukünftig vom Fachpublikum verwendet wird.

    Bücher sind zum einen als Nachschlagewerke parallel zum Computer wie ein Second-Screen nutzbar. Sie bleiben im physischen Zugriff in der Nähe des Schreibtischs, so lange wir damit arbeiten. Sie geraten nicht so leicht in Vergessenheit wie die Liste der “Muss-ich-noch-lesen”-Lesezeichen.

  20. Warum schlägt der clean-code-developer eine feste Anzahl an Büchern pro Jahr vor? Warum? Zu viel, zu wenig?

    Manchmal kommt es gar nicht auf die aktuelle Zahl an, sondern darauf, dass man sich etwas vornimmt. Die Anzahl an Büchern, die man plant zu lesen, sollte realistisch sein - kleine Paperbacks gehen natürlich schneller als die dicken Standards.

  21. Welche unterschiedlichen Reviewarten gibt es? Welche kennt und praktiziert ihr?

    Es gibt tatsächlich sehr viele unterschiedliche Reviewarten - abhängig davon, wie formalisitisch der Prozess ist, welche Gruppe das Review wie durchführt und um welche Dokumente/Produkte es sich handelt. Ein paar Beispiele sind:

    • Pair Programming (als Prozess)

    • Code Review (formell oder informell)

    • Walkthrough

    • Technisches Review

    • Peer Review

    • Inspektion

  22. Welche Fehler können Reviews aufdecken, die durch dynamische Tests nicht (so leicht) aufgedeckt werden können?

    zum Beispiel:

    • Verstöße gegen Coding Conventions

    • missverstandene Anforderungen / logische Fehler

    • Compliance Probleme

  23. Warum werden Reviews als statische Tests bezeichnet?

    Bei statischen Testverfahren wird der Code nicht ausgeführt: es wird also getestet, ohne dass ein Compiler/Interpreter genutzt wird. Damit sind Reviews (wie z.B. auch Schreibtischtests) das statische Gegenstück zu den dynamischen Testverfahren (Unittest, Integrationstest, usw.), bei denen der Code ausgeführt wird.

  24. Welche Dokumente können einem Review unterzogen werden?

    Alle Dokumente, die im Verlauf eines Projekts entstehen, können einem Review unterzogen werden: von den Anforderungsdokumenten über die Entwürfe und den Quell- und Testcode bis zu den vorbereiteten Abnahmeprotokollen. Je wichtiger die Dokumente für den Projekterfolg sind, desto eingehender sollte ein Review-Prozess implementiert sein.

  25. Warum kann sich der doppelte Personaleinsatz beim Pair-Programming lohnen, auch wenn dadurch nicht doppelt so viele Zeilen Code wie bei einem einzelnen Entwickler erzeugt werden?

    Hier greift die gleiche Logik wie bei automatisierten Tests und der Testgetriebenen Entwicklung: ein entwickelndes Paar wird einige Fehler bereits in einer sehr frühen Phase entdecken und ausbessern. Dadurch werden teure Folgekosten der späten Fehlerbehebung vermieden.

Offene Fragen:

  1. Welche Tools nutzt ihr für Issue-Tracking in Eurer Firma?

  2. Welche Bücher / Medien / Periodika liest Du und kannst Du empfehlen?

  3. In welchen Bereichen planst Du, dich fortzubilden?

Allgemeine Begriffe: Was meint clean-code-developer mit…:

Folgende Begriffe werden im Orangenen Grad genannt. Wenn Du sie nicht kennst, solltest Du mal nachschlagen, was sie bedeuten:

  • Kohäsion

  • lose Kopplung

  • Aspektorientierte Programmierung

  • Domain Driven Design


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 orangen 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-oranger-grad-uebung veröffentlicht, die Quelltexte sind in weiterverarbeitbarer Form verfügbar im Repository unter https://gitlab.com/oer-informatik/design-prinzipien/clean-code. Stand: 07.11.2023.

[Kommentare zum Artikel lesen, schreiben] / [Artikel teilen] / [gitlab-Issue zum Artikel schreiben]

Kommentare gerne per Mastodon, Verbesserungsvorschläge per gitlab issue (siehe oben). Beitrag teilen: