• Teaser Home

    Clean Code Developer School

    Saubere Softwareentwicklung üben – regelmäßig, fokussiert, individuell, angeleitet

Der Readiness-Check

Der Readiness-Check

Der Unterricht der CCD School soll sich auf Prinzipien und Praktiken für saubere und flüssige Softwareproduktion konzentrieren. Das setzt die Bekanntheit mit einigen Grundlagen von Programmiersprache und Plattform voraus, um interessante Übungsaufgaben handwerklich zügig absolvieren zu können. Nur so kann der Fokus auf den eigentlichen Lerninhalten bleiben.

Aus diesem Grund hat die CCD School nach einigen Jahren Erfahrung mit Clean Code Trainings eine Liste von wünschenswerten Kompetenzen zusammengestellt. Bitte beurteilen Sie selbst, wie vertraut Sie damit sind; geben Sie sich zu jeder Kompetenz eine Schulnote.

Anschließend versuchen Sie sich an den Übungsaufgaben. Grobe Zeitvorgaben geben Ihnen eine Orientierung für die Selbsteinschätzung. Die Übungsaufgaben sind so gestaltet, dass sie einen Mix der Kompetenzen „abfragen“. Es geht bei der Realisierung ausdrücklich nicht um sauberen Code! Sie dürfen also schnell und dreckig arbeiten – solange Sie die definierten Rahmenbedingungen erfüllen.

Wünschenswerte Kompetenzen

Zeichenkettenoperationen

Wie vertraut sind Sie mit dem Umgang mit Zeichenketten/Strings? In vielen Übungen müssen Zeichenketten analysiert (zerlegt) und zusammengebaut werden. Sie sollten beherrschen:

  • Zeichenketten splitten (an bestimmten Zeichen, Split())
  • Zeichenketten zusammenbauen (+, Join(), StringBuilder)
  • Zeichenketten auf Inhalt prüfen (IndexOf(), StartsWith())
  • Zeichenketten formatieren (Format(), ToLower/Upper())
  • Zeichenketten von/nach char/byte wandeln

Collections

Kennen Sie die grundlegenden abstrakten Datentypen List<T>, Stack<T>, Queue<T>, HashSet<T>, Dictionary<T>?

  • Unterschiede in der Zugriffsart
  • Lesen/Schreiben von Inhalten
  • „Aufzählen“ (Durchlaufen) von Inhalten
  • Prüfen auf Vorhandensein von Inhalten

Iteratoren

Wie funktioniert IEnumerable? Wie funktioniert yield return? Wann lohnt sich der Einsatz von IEnumerable<T> im Vergleich zu Collection-Typen oder Arrays? Die Antwort auf diese Fragen zu kennen, hilft beim Schreiben von sauberem Code. Denn Iteratoren erlauben kürzere, allgemeinere oder schlicht ituitivere Logik zu formulieren.

Insbesondere sollten Sie beherrschen:

  • Große bzw. unbestimmt lange Datenströme als Funktionsresultate erzeugen können

Dateisystemzugriff

Halbwegs interessante Übungsaufgaben brauchen eine Form von Persistenz. Am einfachsten lässt die sich herstellen mit dem Dateisystem und Textdateien. Deshalb ist es wichtig, dass Sie sich damit grundsätzlich auskennen, auch wenn in Ihrem Projektleben nur große Persistenztechnologie wie Oracle, DB2, MS SQL Server usw. zum Einsatz kommen.

  • Navigieren im Dateisystem (Verzeichnishierarchie und Dateien)
  • Dateien/Verzeichnisse auf Existenz prüfen, erzeugen und löschen
  • Textdateien lesen/schreiben
  • Binärdateien als Streams lesen/schreiben
  • Pfadnamen zusammenbauen

I/O auf Konsole

Auch wenn Ein-/Ausgaben über die Konsole (also in einem Terminal-Fenster) nicht recht state-of-the-art zu sein scheinen angesichts von graphischen Benutzeroberflächen und Web-Seiten, hilft solche Art der Benutzerschnittstelle, Übungsaufgaben gerade am Anfang auf das Wesentliche zu konzentrieren. Sie sollten beherrschen:

  • Ausgabe von Zeichenketten auf der Konsole (Standard-Output)
  • Einlesen von Zeichenketten und einzelnen Zeichen von der Konsole (Standard-Input)
  • Zugriff auf Kommandozeilenparameter

Graphische Benutzeroberfläche

Anspruchsvollere Aufgaben brauchen „mehr“ Benutzerschnittstelle. Dafür gibt es viele Optionen (WinForms, WPF, Gtk#, ASP.NET). Bei aller Unterschiedlichkeit finden sich jedoch Gemeinsamkeiten, mit denen Sie vertraut sein sollten:

  • Eingabe von ein-/mehrzeiligen Texten
  • Anzeige von Texten (Label)
  • Optionsschalter (Checkbox)
  • Combobox
  • Liste von Einträgen mit mehreren Spalten
  • Schaltfläche/Button
  • Anzeige von Nachrichten (Messagebox)
  • Modale/nicht modale Fenster

Es geht nicht um spezielle Muster (MVC, MVP, MVVM) oder Frameworks. Auch Databinding wie in WinForms oder WPF/XAML ist nicht wichtig. Sie sollten jedoch fähig sein, flüssig einfache Benutzeroberflächen bestehend aus den obigen Elementen zusammenzusetzen.

Funktionstypen

Funktionen tun nicht nur etwas, sie stellen auch Daten dar. Jedenfalls heutzutage in den meisten Programmiersprachen. Das bedeutet, man kann Funktionen nicht nur aufrufen, sondern auch zuweisen wie Zahlen oder Zeichenketten. Das ermöglicht sehr vorteilhafte Muster für die saubere Programmierung. Deshalb sollten Sie – sofern in Ihrer Programmiersprache verfügbar – vertraut sein mit:

  • Funktionszeiger (.NET: delegate)
  • Lambda-Ausdrücke
  • Closure
  • Action<T>, Func<T,T>
  • Linq

Unit Testing

Saubere Programmierung bedeutet nicht notwendig, strenges Vorgehen nach TDD. Aber automatisierte Tests gehören dazu. Sie sollten daher zumindest mit den Grundlagen eines Unit Testing Frameworks (z.B. NUnit, JUnit, MS Test) vertraut sein:

  • Testfunktionen definieren (TestFixture, Test)
  • Erwartungen überprüfen (Assert)
  • Testframework einbinden in ein Projekt
  • Tests automatisiert ausführen in der IDE

Übungsaufgaben

Stack im Selbstbau (15min)

Entwickeln Sie eine generische Klasse, die den Abstrakten Datentyp (ADT) Stack/LIFO implementiert. Die Methoden sollten sein:

  • Push – ein Element auf den Stack legen
  • Pop – ein Element vom Stack entfernen
  • Count – Anzahl der Elemente im Stack
  • Peek – das oberste Element auf dem Stack liefern, ohne es zu entfernen
  • Clear – Stack leeren

Benutzen Sie eine List-Collection, um die Elemente intern zu verwalten. Stützen Sie Ihre Implementation mit automatisierten Tests.

Queue im Selbstbau (30min)

Entwickeln Sie eine generische Klasse, die den ADT Queue/FIFO implementiert. Die Methoden sollten sein:

  • Enque – ein Element in die Warteschlange stellen
  • Dequeue – ein Element aus dem Warteschlange entfernen
  • Count – Anzahl der Elemente in der Warteschlange
  • Peek – das vorderste Element, ohne es zu entfernen
  • TryDequeue – wie Dequeue, allerdings keine Exception, falls die Queue leer; liefert true/false, jenachdem, ob Dequeue erfolgreich

Benutzen Sie keinen Collection-Typ und auch kein Array, um intern die Elemente zu verwalten. Stützen Sie Ihre Implementation mit automatisierten Tests.

UPN Rechner (50min)

Entwickeln Sie ein Konsolenprogramm zur Auswertung von UPN-Ausdrücken. Benutzungsbeispiel:

Der Ausdruck wird nach dem Programmnamen eingegeben. Das Ergebnis wird auf Standard-Output ausgegeben.

Erkannt werden ganze Zahlen mit einer oder mehreren Ziffern. Erlaubte Operatoren: +, -, *, /

Whitespace im Ausdruck ist nicht signifikant. Falls der Ausdruck in „“ eingeschlossen werden muss auf der Kommandozeile, ist das ok. Es sollte aber auch so weit möglich ohne funktionieren.

Benutzen Sie intern einen Stack<T> während der Auswertung.

Decken Sie die Logik weitgehend mit automatisierten Tests ab.

Textumbruch (75min)

Entwickeln Sie ein Programm mit graphischer Benutzerschnittstelle, um Texte umzubrechen. Der Text wird in einem mehrzeiligen Textfeld eingegeben (oder aus dem Clipboard eingefügt).

„Auf Knopfdruck“ wird er auf eine Breite umgebrochen, die in einem weiteren Feld spezifiziert wurde. (Bereich für die Breite: 5 bis 100 Zeichen)

Keine Zeile soll dann länger als diese Maximalbreite sein. Worte, die länger als die Maximalbreite sind, werden nicht geteilt. Absätze sollen erhalten bleiben, d.h. Gruppen von Textzeilen, die durch eine Leerzeile getrennt sind.

Satzzeichen werden nicht von Worten getrennt. D.h. beim Umbruch von „Er fragte, wohin gehen wir.“ mit Maximalbreite 9 würde „fragte,“ nicht mehr in der ersten Zeile stehen.

Leerzeichen müssen nicht in ursprünglicher Menge erhalten bleiben.

Der umgebrochene Text ersetzt den ursprünglichen.

Dateien suchen (90min)

Entwickeln Sie ein Programm mit graphischer Benutzerschnittstelle, um Dateien zu suchen. Der Benutzer gibt einen Verzeichnispfad und ein Suchwort ein. Wenn er dann die Suche startet, werden gefundene Dateien mit Name, Verzeichnispfad, Dateilänge in drei Spalten in einer Liste angezeigt.

Jede gefundene Datei wird sofort angezeigt.

Während der Suche wird die Zahl der geprüften Dateien und die der gefundenen ständig aktualisiert.

Eine Datei gilt als gefunden, wenn ihr Name das Suchwort enthält oder ihr Inhalt. Der Inhalt wird allerdings nur geprüft, wenn es sich um eine Textdatei handelt (Endungen .cs, .txt, .csv, .xml).

Todo-Liste verwalten (150min)

Entwickeln Sie ein Programm mit graphischer Benutzerschnittstelle zur Verwaltung einer ToDo-Liste.

Jeder Listeneintrag besteht aus Beschreibung und Fälligkeitsdatum.

Wenn das Fälligkeitsdatum erreicht ist, wird der Listeneintrag hervorgehoben (z.B. rote Einfärbung).

Die Listeneinträge können angelegt, bearbeitet und gelöscht werden. Die Wichtigkeit eines Eintrags zeigt seine Position in der Liste an. Die kann ebenfalls verändert werden.

Die Einträge sollen über Anwendungsstarts hinweg erhalten bleiben. Die Anwendung wird nur lokal von einem Benutzer verwendet.