Bernhard Findeiss
Dienstag, der 25. Oktober 2011

Handwerklich gut gemachte Software – für viele ein zu hoher Anspruch?

In den letzten Monaten habe ich mich zusehends mit Software Craftsmanship beschäftigt.  Eine der spannendsten Thesen darin ist die Forderung:

„Not only working software, but also well-crafted software“ (siehe hier).

Hinter diesem so einfach klingenden Satz verbirgt sich für mich ein Thema mit einigem Diskussionspotential. Natürlich ist eine funktionierende Software immer besser als ein Schrank voller Ordner mit Spezifikationsdokumenten auf totem Baum.

Jedoch gehen bereits die Vorstellungen darüber, was man unter „funktionierender Software“ zu verstehen hat, teils weit auseinander: Der einfachsten Definition nach würde es bereits ausreichen, einen kompilierfähigen Quellcode zu haben. Doch reicht das schon? Besser wäre es, den Quellcode vor der Auslieferung nicht nur zu kompilieren, sondern auch tatsächlich mal laufen zu lassen. Zudem besteht zumindest die entfernte Möglichkeit, daß die allererste Version der Software evtl. nicht der ganz große Wurf ist. Insofern wäre es auch nicht schlecht, sich zumindest im Grundsatz schon mal Gedanken zu den Themen Lesbarkeit, Wartbarkeit und Erweiterbarkeit zu machen.

Ein fertiger Quellcode fällt auch nicht einfach so vom Himmel. Irgendwer muß ihn mal schreiben. Nun ist das Schreiben von Code im Jahr 2011 nicht in jedem Fall mehr ein Fall für eine einzelne Person, die sich mit einem einfachen Texteditor („vi“) aufmacht, Texte zu tippen. Vielmehr gibt es heute für die meisten Programmiersprachen ausgefeilte Entwicklungsumgebungen. Diese haben einen typischerweise einen solch riesigen Funktionsumfang, daß man sich schon ein wenig einarbeiten muss, bevor sich die in Aussicht gestellten Vorteile gegenüber dem althergebrachten Texteditor einstellen.

Eine weitere, für so manchen Programmierer nicht zu verachtende Hürde ist dann erreicht, wenn man nicht mehr alleine, sondern im Team an einer Software arbeitet. Arbeiten sollten nun idealerweise abgesprochen werden. Zudem müssen die Quelltexte nun irgendwie zwischen den verschiedenen Teammitgliedern abgeglichen werden. Das manuelle Kopieren und Synchronisieren ganzer Ordnerstrukturen in verschiedenen Arbeitsverzeichnissen hat sich dabei, obwohl immer noch gerne eingesetzt, nicht in allen Fällen als die beste Lösung erwiesen. Stattdessen benutzt man dafür heute in den meisten Fällen Versionskontrollsysteme wie CVS, SVN oder Git.

Hier kommt auch noch erschwerend hinzu, daß man die in der Vergangenheit oft sehr strikte Aufteilung des Quellcodes in disjunkte Pakete unter den einzelnen Teammitgliedern in den letzten Jahren oftmals aufgeweicht oder sogar ganz aufgegeben hat (Stichwort: „Collective Code Ownership“). Konflikte beim „Einchecken“ ins Versionskontrollsystem sind daher schon vorgezeichnet. Konfliktlösungsstrategien müssen also her! Hier z.B. hat es sich bewährt, sich mit seinen Kollegen kurz abzusprechen.

Soweit eine aus meiner Sicht etwas mehr an der tatsächlichen Realität orientierte Definition von „Working Software“. Was nun noch fehlt ist der Schritt zu handwerklich guter Software.

Dieser Schritt beinhaltet selbstverständlich alle die gerade genannten Punkte. Doch das alleine reicht für mich noch lange nicht. Ausgehend davon, was im Jahre 2011 alles möglich mit vertretbarem Aufwand möglich ist, gehören zu wirklich gut gemachter Software für mich noch die folgenden Dinge:

  • Lesbarkeit: Quellcode soll kein „Spaghetti“-Code sein, sondern in einfache, logische und verständliche Strukturen aufgebrochen werden. Alle Möglichkeiten einer modernen, objektorientieren Architektur sollten dabei genutzt werden. Mir ist natürlich klar, daß nicht jede Programmiersprache Objektorientierung unterstützt. Doch auch bei funktionalen Sprachen kann man lesbaren Code schreiben.
  • Kommentare: Dieser Punkt schliesst nahtlos an den obigen Punkt an. Es reicht nicht, nur lesbaren Code zu schreiben. Man sollte auch mit Kommentaren nicht sparsam sein. Moderne IDEs unterstützen einem dabei mit eingebauten Vorlagen, die man nur noch entsprechend ausfüllen muß. Der nächste, der am Code arbeitet, wird es einem danken (auch wenn man es selbst ist, einige Monate später)
  • Testgetriebene Entwicklung: Auf keinen Fall sollte man vergessen, den erstellten Quellcode durch Testfälle abzusichern. Dazu zählen u.a. Unit-Tests, Lasttests, Akzeptanz- und GUI-Tests. Nur so traut man sich z.B. auch in späteren Projektphasen noch, Änderungen an wichtigen Systemkomponenten vorzunehmen. Und dass solche Änderungen nötig werden, dafür sorgt alleine schon Murphy’s Law.
  • Kontinuierliche Integration: Eine Technik aus dem Extreme Programming, die sich in den letzten Jahren zusehends durchgesetzt hat. Darunter versteht man das regelmäßige, vollständige Bauen und Testen einer Anwendung. Regelmäßig in dem Sinne, daß man Integrationsläufe am besten bei jedem Check-In ins Versionsverwaltungssystem anstösst (so möglich), mindestens aber 1x pro Stunde. Auf diese Art und Weise bekommt das Entwicklungsteam sehr schnell Feedback, wie sich das Projekt entwickelt. Als neutrale Instanz, die immer auf einer frischen Kopie des Quellcodes arbeitet, warnt der CI-Server sehr zuverlässig vor fehlschlagenden Tests oder nicht kompilierfähigem Quellcode. Seiteneffekte, bei denen Änderungen an einer Stelle im Quellcode die Funktionsweise an einer ganz anderen Stelle beeinflussen oder gar stören können, können so vermieden werden. Langwieriges Fehlersuchen im Entwicklungsteam bleibt einem dadurch oftmals erspart.

Gerade der letzte Punkt ist für ich besonders wichtig. Eröffnet einem doch erst die kontinuierliche Integration die folgenden, jedoch sehr wichtigen Möglichkeiten:

Berechnen der Testabdeckung: Wieviel Prozent ihres Quellcodes wird durch automatisierte Testfälle abgedeckt? Welche Klassen und Pakete sind gut abgedeckt, welche weniger gut? Gute Tools können dies sogar bis auf den Quellcode runterbrechen: Zeilen die abgedeckt sind, werden grün hinterlegt, die es nicht sind, rot hinterlegt. Mittels entsprechender Plugins lässt sich das sogar direkt in der jeweiligen Entwicklungsumgebung (z.B. Eclipse) anzeigen

Auf Knopfdruck auszurollen: Wenn man schon so weit ist, eine Software automatisiert zu bauen und zu testen, so liegt es  ziemlich nahe, die gebaute Software auch gleich auf eine entsprechende Umgebung zu deployen (z.B. Test, Integration oder Produktion). Je nach Umgebung und Systemumgebung sieht dieser Schritt immer ein wenig anders aus. Es lohnt sich jedoch auf alle Fälle! Übrigens ist dieses „One touch deployment“ aktuell eines der neuesten Hype-Themen im Bereich agiler Softwareentwicklung.

Code-Metriken errechnen: Die Testabdeckung ist nur eine von vielen möglichen Code-Metriken. Je nach Art der zu entwickelnden Software machen auch noch andere Metriken Sinn. Üblich sind z.B. Code-Qualität (nach verschiedenen Richtlinien), Code-Komplexität, die Einhaltung von Programmier- und Architekturstandards. Ein gebräuchliches Produkt in diesem Bereich ist übrigens „Sonar“, das ich auch aus eigener Erfahrung sehr empfehlen kann (mehr Info hier)

Diese Liste ist jedoch nicht hinreichend. Eher ein minimaler Satz an Regeln für  gute Software: Damit sich eine Software aus meiner Sicht überhaupt „handwerklich gut“ nennen darf, muss sie zumindest alle diese Punkte erfüllen.

Leider kommt es mir aktuell aber immer noch so vor, daß die Mehrzahl aller IT-Projekte von diesem Standard noch weit entfernt sind. Als IT-Profis sollten wir jedoch einen gewissen Anspruch an uns selbst und unsere Arbeit haben. Für die  unter „funktionierende Software“ genannten Punkte erübrigt sich für mich sogar jegliche Diskussion – jedwede Software, die nicht alle diese Punkte erfüllt, ist für mich nichts anderes als unprofessionell.

Doch dieser Anspruch ist aus meiner Sicht viel zu niedrig. Es sollte für uns immer das Ziel sein, handwerklich gute Software zu produzieren!

Wer sich davon nun überfordert fühlt, sollte sich jedoch nicht grämen: Für alle diese Bereiche gibt es mittlerweile viele Beispiele und Materialien. Vieles davon im Netz und für umsonst zu haben. Auch viele  gängige Tools, die in diesen Bereichen eingesetzt werden, sind Open Source Entwicklungen und somit legal für umsonst zu haben.

Die Einstiegshürde ist also denkbar gering. Wichtig ist nur, damit anzufangen…

BFI

Be Sociable, Share!

1 Kommentar zu “Handwerklich gut gemachte Software – für viele ein zu hoher Anspruch?”

  1. Hans Bonfigt (Mittwoch, der 26. Oktober 2011)

    Man könnte ja vielleicht sogar eine Stufe vorher ansetzen:

    – Möchte ich in einer Sprache programmieren, die keinen
    expliziten Typ für alphanumerische Zeichenketten
    implementieren (die kommen ja praktisch nie vor)
    oder
    – eine Sprache verwenden, bei der ich das Ergebnis
    einer Rechenoperation nicht auf Überlauf abfragen
    kann
    oder
    – gezwungen werde, üble casts zu verwenden und damit
    jede Typisierung pervertiere
    oder
    – es ertragen muß, daß gleiche Statements (‚break‘)
    kontextabhängig eine völlig unterschiedliche Seman-
    tik haben
    oder, oder, oder …

    Man kommt dann oft zu dem traurigen Ergebnis, daß eine
    moderne IDE nur eine Art Schminke ist, die uralte
    Narben zukleistern sollen.

    Das ist – genau wie der scheußliche BMW-Geländewagen-
    verschnitt, in dem ich heute herumchauffiert wurde –
    nicht modern, sondern dekadent.

    Seit mehr als dreißig Jahren, die ich mit Assembler,
    C, Fortran, COBOL – Nixdorf ‚Business Basic‘ hätte
    ich jetzt fast verdrängt – und jeder Menge anderer
    Spielereien verbracht habe, warte ich auf eine moder-
    ne Programmiersprache.

    Und weil ich die nicht kriege, belasse ich es bei ‚C‘
    und hübsche meine Elaborate auch nicht auf.

    Also, wenn jemand schreibt,
    if (15==x) …
    weil er damit verhindern will, daß er versehentlich
    Wertzuweisung und Vergleichsoperator tauscht der be-
    treibt m.E. F.D.P. – Programmierung:
    Peinlich wie Westerwelle und produktiv wie Frau
    Koch-Mehrin.

    Prominente Beispiele zeigen:
    Je einfacher man es dem Programmierer macht, desto
    mehr Bockmist baut er.

    Die Stolperfallen in C und dessen Aussehen wie
    Babylonische Keilschrift wirken wie ein Fliegengitter,
    mit welchem man Wertvolles vor Ungeziefer schützt.

    An Java traut sich jeder ran – mit den bekannten
    Nebenwirkungen.

Kommentar verfassen

*