README Dateien haben in Softwareprojekten eine lange Tradition. Diese ursprünglich reinen Textdateien enthielten Lizenzinformationen und Anweisungen wie aus dem Quellcode das entsprechende Artefakt kompiliert werden konnte oder aber wichtige Hinweise zu Installation des Programms. Es gibt keinen wirklichen Standard wie man eine solche README Datei aufbauen sollte.
Seit dem GitHub (2018 von Microsoft übernommen) als kostenfrei Code Hosting Plattform für Open Source Projekte seinen Siegeszug angetreten ist, gab es schon recht früh die Funktion, dass die README Datei als Startseite des Repositories anzuzeigen. Dazu muss lediglich eine einfach Textdatei mit der Bezeichnung README.md im Hauptverzeichnis des Repository erstellt werden.
Um die README Dateien übersichtlicher strukturieren zu können wurde eine Möglichkeit für eine einfache Formatierung gesucht. Schnell hatte man sich für die markdown Notation entschieden, da diese einfach zu nutzen ist und auch recht performant gerendert werden kann. Somit sind die Übersichtsseiten besser für Menschen zu lesen und können als Projekt Dokumentation genutzt werden.
Es ist möglich mehrere solcher markdown Dateien als Projektdokumentation miteinander zu verknüpfen. Somit erhält man eine Art Mini WIKI das im Projekt enthalten ist und außerdem auch über Git versioniert wird.
Das ganze wurde so erfolgreich, das Selfhosting-Lösungen wie GitLab oder das kommerzielle BitBucket diese Funktion ebenfalls übernommen haben.
Nun stellt sich aber die Frage welche Inhalte man am besten in solch eine README Datei schreibt, damit diese für Außenstehende auch einen wirklichen Mehrwert darstellen. Dabei haben sich im Laufe der Zeit folgende Punkte etabliert:
Kurzbeschreibung des Projektes
Bedingungen unter denen der Quellcode verwendet werden darf (Lizenz)
Wie ist das Projekt zu verwenden (z.B. Anweisungen zum Compilieren oder wie wird die Bibliothek in eigene Projekte eingebunden)
Wer sind die Autoren des Projekte und wie kann man sie erreichen
Was ist zu tun wenn man das Projekt unterstützen möchte
Mittlerweile sind sogenannte Badges (Sticker) sehr populär. Diese referenzieren oft auf externe Dienste wie beispielsweise der freie Continuous Integration Server TravisCI. Diese helfen ausstehenden die Qualität des Projektes zu beurteilen.
Auf GitHub gibt es auch diverse Vorlagen für README Dateien. Man muss allerdings auch ein wenig auf die tatsächlichen Gegebenheiten des eigenen Projektes schauen und beurteilen welche Information für Nutzer bzw. Anwender wirklich relevant sind. Solche Vorlagen helfen aber sehr dabei herauszufinden ob man möglicherweise eine Punkt übersehen hat.
Das mittlerweile ziemlich jeder Hersteller von Source Control Management Serverlösungen die Funktion die README.md Datei als Projektstartseite für das Code Repository anzuzeigen integriert hat, bedeutet das eine README.me auch für kommerzielle Projekte eine sinnvolle Sache sind.
Auch wenn der Syntax für markdown leicht zu erlernen ist kann es bei umfangreichen Editierungen solcher Dateien durchaus komfortabler sein direkt eine MARKDOWN Editor zu nutzen. Dabei sollte man darauf achten, das die Vorschau auch korrekt dargestellt wird und nicht nur ein einfaches Syntaxhighligting angeboten wird.
Sämtlich in einem Unternehmen aufgestellten Regeln und durchgeführten Aktivitäten stellen Prozesse dar. Deswegen kann auch pauschal gesagt werden, das die Summe der Prozesse eine Organisation beschreibt. Leider sind manchmal die Prozesse so kompliziert gestaltet, das diese sich negativ auf das Unternehmen auswirken. Was kann also getan werden um die Situation zu verbessern?
(c) 2022 Marco Schulz, JAVA aktuell Ausgabe 6
Laut ISO 900 Definition ist ein Prozess, ein Satz von in Wechselbeziehung stehenden Tätigkeiten. der Eingaben in Ergebnisse umwandelt. Dabei spielt es keine Rolle, ob der Prozess atomar ist, also nicht weiter zerlegt werden kann oder aus mehreren Prozessen zusammengesetzt wurde. An dieser Stelle ist es wichtig auch kurz auf einige Begriffe einzugehen.
Choreographie: beschreibt einzelne Operationen, aber nicht die Nachrichtenreihenfolge (Ablauf). Es behandelt die etablierte Kommunikation zwischen zwei Teilnehmern.
Orchestration: beschreibt die Reihenfolge und Bedingungen der aufrufenden Teilprozesse.
Konversation: beschreibt die Abfolgen zwischen Prozessen. Es wird die gesamte zulässige Kommunikation (Vollständigkeit) zwischen zwei Teilnehmern beschrieben.
Die aufgeführten Begrifflichkeiten spielen für die Beschreibung von Prozessen eine wichtige Rolle. Wenn sie beispielsweise die Idee haben die für Ihr Unternehmen wichtigen Geschäftsprozesse in einem Prozessbrowser visualisiert darzustellen, müssen Sie sich bereits im Vorfeld über die Detailtiefe der bereitgestellten Informationen im Klaren sein. Sollten Sie die Absicht hegen möglichst alle Informationen in so einem Schaubild einzubringen, werden Sie schnell feststellen wie sehr die Übersichtlichkeit darunter leidet. Wählen Sie daher immer für die benötigte Anwendung die geeignete Darstellung aus.
Ansichtssachen
Hier kommen wir auch schon zur nächsten Fragestellung. Was sind geeignete Mittel um Prozesse verständlich darzustellen. Aus persönlicher Erfahrung hat sich in meinen Projekten ein Darstellung über den Informationsfluss gut bewährt. Dazu wiederum nutze ich die Business Process Model Notation, kurz BPMN die für solche Zwecke geschaffen wurde. Ein frei verfügbares Werkzeug um BPMN Prozesse aufzuzeichnen ist der BigAzi Modeler [1]. Die Möglichkeit aus BPMN Diagrammen wiederum softwaregestützte Programme mittels serviceorientierter Architekturen (SOA) zu erzeugen ist für ein Großteil der Unternehmen weniger nutzbringend und nicht so einfach umzusetzen wie es auf den ersten Blick scheint. Viel wichtiger bei einer Umsetzung zur grafischen Darstellung interner Unternehmensprozesse sind die so zu tage geförderten versteckten Erkenntnisse über mögliche Verbesserungen.
Besonders Unternehmen, die eine eigenständige Softwareentwicklung betreiben und die dort angewendeten Vorgehensweisen, möglichst in einem hohen Grade automatisieren wollen, können den Schritt zur Visualisierung interner Strukturen selten auslassen. Die hier viel zitierten Stichwörter Continuous Integration, Continuous Delivery und DevOps haben eine sehr hohe Automatisierungsstufe zum Ziel. Um in diesem Bereich erfolgreiche Ergebnisse erreichen zu können, ist es unumgänglich möglichst einfache und standardisierte Prozesse etabliert zu haben. Das beschreibt auch das Paradoxon der Automatisierung.
Prozessautomation reduziert das Risiko, dass Fehler gemacht werden. Aber hochkomplexe Prozesse sind naturgemäß nur sehr schwer zu automatisieren!
Wenn Sie den Entschluss gefasst haben die hauseigenen Geschäftsprozesse zu optimieren benötigen Sie selbstredend zuerst eine realistische Analyse des aktuellen IST – Zustands um daraus den gewünschten SOLL – Zustand zu beschreiben. Sobald diese beiden wichtigen Punkte feststehen können Sie geeignete Maßnahmen ergreifen, mit der sie die Transformation vollziehen können.
Abbildung 1: Die Transformation von der Ausgangssituation hin zu Zielstellung.
Es wäre an dieser Stelle nicht sehr hilfreich verschiedene Vorgehnsmodelle zu beschreiben, wie eine solche Transformation von statten gehen kann. Solche Vorhaben sind stets sehr individuell und den tatsächlichen Gegebenheiten im Unternehmen geschuldet. Hier sei Ihnen nur ein wichtiger Ratschlag mit auf den Weg gegeben. Gehen Sie kleine einfache Schritte und vermeiden Sie es möglichst alles auf einmal umsetzen zu wollen. Manchmal entdecken Sie während einer Umstellung wichtige Details die angepasst werden müssen. Das gelingt Ihnen gefahrlos wenn Sie genügend Reserven eingeplant haben. Sie sehen auch hier spiegeln sich agile Gedanken wieder, die Ihnen die Möglichkeit geben direkt auf Veränderungen einzugehen.
Richten Sie Ihr Augenmerk vor allem auf den zu erreichenden Sollzustand. Im Großen und Ganzen wird zwischen zwei Prozesstypen unterschieden. Autonome Prozesse laufen im Idealfall vollständig automatisiert ab und erfordern keinerlei manuelles Eingreifen. Dem gegenüber stehen die interaktiven Prozess, welche an ein oder mehreren Stellen auf eine manuelle Eingabe warten um weiter ausgeführt werden zu können. Ein sehr oft angestrebtes Ziel für den SOLL – Zustand der Prozesslandschaften sind möglichst kompakte und robuste autonome Prozesse um den Automatisierungsgrad zu verbessern. Folgende Punkte helfen Ihnen dabei das gesteckte Ziel zu erreichen:
Definieren Sie möglichst atomare Prozesse, die ausschließlich einen einzigen Vorgang oder einen Teilaspekt eines Vorgangs beschreiben.
Halten Sie die Prozessbeschreibung möglichst sehr einfach und orientieren Sie sich dabei an vorhanden Standards und suchen Sie nicht nach eigenen individuellen Lösungen.
Vermeiden Sie so gut es möglichst jegliche manuelle Interaktion.
Wägen Sie bei Ausnahmen sehr kritisch ab, wie oft diese tatsächlich auftreten und suchen Sie nach möglichen Lösungen diese Ausnahmen mit dem Standartvorgehen abarbeiten zu können.
Setzen Sie komplexe Prozessmodelle ausschließlich aus bereits vollständig beschriebenen atomaren Teilprozessen zusammen.
Sicher stellen Sie sich die Frage, was es mit meinem Hinweis auf die Verwendung von etablierten Standards auf sich hat. Viele der in einem Unternehmen auftretenden Probleme wurden meist bereist umfangreich und bewährt gelöst. Nicht nur aus Zeit und Kostengründen sollte bei der Verfügbarkeit bereits etablierter Vorgehensmodelle kein eigenes Süppchen gekocht werden. So erschweren Sie zum einem den Wissenstransfer zwischen Ihren Mitarbeitern und zum anderen erschweren Sie die Verwendung von standardisierter Branchensoftware. Hierzu möchte ich Ihnen ein kleines Beispiel aus meinem Alltag vorstellen, wo es darum geht in Unternehmen möglichst automatisierte DevOps Prozesse für die Softwareentwicklung und den Anwendungsbetrieb zu etablieren.
Die Kunst des Loslassen
Die größte Hürde die ein Unternehmen hier nehmen muss, ist eine Neuorientierung an dem Begriff Release und dem dahinterliegenden Prozess, der meist eigenwillig interpretiert wurde. Die Abweichung von bekannten Standards hat wiederum mehrere spürbare Folgen. Neben erhöhtem Personalaufwand für die administrativen Eingriffe im Releaseprozess besteht auch stets die Gefahr durch unglückliche äußere Umstände in zeitlichen Verzug zum aktuellen Plan zu geraten. Ohne auf die vielen ermüden technischen Details einzugehen liegt das gravierendste Missverständnis in dem Glauben es gäbe nach dem Erstellen eines Releases noch die Möglichkeit die in der Testphase erkannten Fehler im selben Release zu beheben. Das sieht dann folgendermaßen aus: nach einem Sprint wird beispielsweise das Release 2.3.0 erstellt, welches dann ausgiebig in der Testphase auf Herz und Nieren überprüft wird. Stellt man nun ein Fehler fest, ist es nicht möglich eine korrigiert Version 2.3.0 zu erzeugen. Die Korrektur hat ein neues Release zur Folge, welches dann die Versionsnummer 2.3.1 trägt. Ein wichtiger Standard der hier zum Tragen kommt ist die Verwendung des Semantic Versioning, welcher jedem einzelnen Segment der Versionsnummer eine Bedeutung zuordnet. In dem hier verwendeten Beispiel zeigt die letzte Stelle die für ein Release durchgeführten Korrekturen an. Falls Sie sich etwas intensiver mit dem Thema Semantic Versioning beschäftigen mögen, empfehle ich dazu die zugehörige Internetseite [2].
Was aber spricht nun dagegen ein bereits geplantes und auf den Weg gebrachtes Release bei der Detektion von Fehlern nicht zu stoppen, zu korrigieren und ‘repariert’ erneut unter der bereits vergebenen Versionsnummer auf den Weg zu schicken? Die Antwort ist recht einfach. Der erhebliche Arbeitsaufwand, welcher ausschließlich manuell durchgeführt werden muss, um den Fehler wieder auszubügeln. Abgesehen davon wird Ihre gesamte Entwicklungsarbeit für das Folgerelease erheblich ausgebremst. Ressourcen können nicht frei gegeben werden und der Fortschritt beginnt zu stagnieren.
Deswegen ist es wichtig sich so zu disziplinieren, das ein bereits auf den Weg gebrachtes Release sämtliche Prozeduren durchläuft und erst im letzten Schritt dann die manuell ausgeführte Entscheidung getroffen wird, ob das Release für den Produktive Einsatz auch geeignet ist. Deswegen rate ich grundsätzlich dazu den Begriff Release Kandidat aus dem Sprachgebrauch zu streichen und besser von einem Production Kandidat zu sprechen. Diese Bezeichnung spiegelt den Releaseprozess viel deutlicher wieder.
Sollten sich währen der Testphase Mängel aufzeigen, gilt zu erst zu entscheiden wie schwerwiegend diese sind und deren Behebung ist zu priorisieren. Das kann soweit gehen, das direkt ein Korrekturrelease auf den Weg gebracht werden muss, während parallel der nächste Sprint abgearbeitet wird. Weniger gravierende Fehler können dann auf die nächsten Folgesprits verteilt werden. Wie das alles in der täglichen Praxis umgesetzt werden kann – habe ich letztes Jahr in meinem Vortag “Rolling Stones: Vom Release überrollt” auf der JCON präsentiert. Den Videomitschnitt finden Sie frei zugänglich im Internet.
Unter dem Gesichtspunkt der Prozessoptimierung bedeute es für das aufgeführte Beispiel des Release Prozesses, das der Prozess beendet wurde, wenn aus dem Sourcecode erfolgreich eine binäres Artefakt mit einer noch nicht belegten Versionsnummer erstellt werden konnte. Das so entstandene Release wird umgehend an einer zentralen Stelle veröffentlicht (deliverd), wo es in den Testprozess übergeben werden kann. Erst wenn der Testprozess mit dem Ergebnis abgeschlossen wurde, dass das erzeugte Release auch in Produktion verwendet werden darf erfolgt die Übergabe in den Deployment Prozess. Sie sehen, das was vielerorts als ein gesamter Prozess angesehen wird ist genau betrachtet eine Orchestration aus mindestens 3 eiegnständigen Prozessen.
Abbildung 2 : Continuous Delivery und Continuous Deployment.
Ein wichtiger Punkt den Sie In Abbildung 2 zum Thema DevOps ebenfalls herauslesen können ist, das der Schritt zwischen Continuous Delivery und Continuous Deployment besser nicht vollautomatisiert werden sollte, denn Deplyoment meint in diesem Kontext nicht das automatisierte bereitstellen der Anwendung auf allen verfügbaren Testinstanzen. Continuous Deployment meint in erste Linie ein automatisiertes Einsetzen der Anwendung in Produktion. Ob das immer eine gute Idee ist sollt sehr sorgfältig abgewogen werden.
Ein wertvoller Aspekt der Prozessbeschreibung in Organisationen ist die Ausarbeitung wichtiger Kriterien die erfüllt sein müssen, damit ein Prozess autonom ablaufen kann. Mit diesem Wissen können Sie bei der Evaluierung benötigter Werkzeuge sehr leicht einen Anforderungskatalog mit priorisierten Punkten erstellen, der einfach abgearbeitet wird. Kann das ins Auge gefasste Tool die aufgelisteten Punkte zufriedenstellend lösen und der aufgerufene Preis passt auch ins Budget, ist Ihre Suche erfolgreich beendet.
Fazit
Sehr oft wird mir entgegengebracht, das durch moderne DevOps Strategien der klassische Release Prozess obsolet geworden ist. Dem kann ich nicht zustimmen. Es mag wenige Ausnahmen geben, in den Unternehmen tatsächlich jede Codeänderung sofort in Produktion bringen. Aus Gründen der Gewährleistung und Haftung, kommt für viel Firmen ein so vollständig automatisiertes Vorgehen aber nicht in Frage. Auch der Datenschutz sorgt dafür, das die Bereich Entwicklung und Betrieb voneinander getrennt werden. Zudem benötigen umfangreiche Softwareprojekte auch eine strategische Planungsinstanz über die umzusetzenden Funktionalitäten. Diese Entscheidbarkeit wird auch künftig nicht beim Entwickler liegen, ganz gleich wie hervorgehoben der Punkt DevOps in der Stellenbeschreibung auch sein mag.
Wie Sie sehen ist das Thema der Prozessbeschreibung und Prozessoptimierung nicht ausschließlich ein Thema für produzierende Branchen. Auch der vielrorts detailreich beschriebene Softwareentwicklungsprozess hält einiges an Verbesserungspotenzial bereit. Ich hoffe ich konnte Sie mit meinen Zeilen ein wenig für das Thema sensibilisieren, ohne zu sehr ins technische verfallen zu sein.
Das Scheitern von Projekten ist Gegenstand vieler Publikationen. Seit Jahrzehnten versucht man diesem Umstand durch verschiedenste Methodiken und Werkzeuge mehr oder minder erfolgreich beizukommen. Obwohl auf den ersten Blick die Gründe eines Misserfolges mannigfaltig scheinen, kann überwiegend schlechtes Management als Problemquelle identifiziert werden. So verweist auch der nachfolgend übersetzte Artikel von Yegor Bugayenko, welche Umstände dafür sorgen tragen können, das Projekte in schlechtes Fahrwasser geraten.
Wartbarkeit gehört zu den wertvollsten Tugenden moderner Software Entwicklung. Eine einfache Möglichkeit Wartbarkeit zu messen, besteht darin die Arbeitszeit zu messen, welche ein Entwickler benötigt um in einem neuen Projekt eigenständig ernsthafte Änderungen vorzunehmen. Je mehr Zeit benötigt wird um so schlechter ist die Wartbarkeit. In einigen Projekten ist diese Zeitanforderung beinahe unendlich. Was einfach ausgedrückt bedeutet, das diese Projekte schlichtweg nicht wartbar sind. Ich glaube das es sieben fundamentale und fatale Anzeichen gibt, das Projekte unwartbar werden. Hier sind sie:
1. Anti-Pattern
Unglücklicherweise sind die Programmiersprachen, welche wir benutzen zu flexibel. Sie ermöglichen zu viel und unterbinden zu wenig. Java zum Beispiel, besitzt keine Restriktionen ein ganze Anwendung mit ein paar tausend Methoden in nur eine Klasse zu packen. Technisch gesehen wird die Anwendung kompilieren und laufen, dennoch handelt es sich um das bekannte Anti-Pattern God Object.
Somit sind Anti-Pattern technisch akzeptierte Möglichkeiten eines Entwurfes, welcher allgemein als schlecht anerkannt ist. Es gibt für ede Sprache unzählige Anti-Pattern. Ihre Gegenwartin unserem Produkt is gleichzusetzen mit einem Tumor in einem lebendem Organismus. Wenn er einmal beginnt zu wachsen ist es sehr schwierig ihm Einhalt zu gebieten. Möglicherweise stirbt der gesamte Organismus. Möglicherweise muss die gesamte Anwendung neu geschrieben werden, weil sie unwartbar geworden ist.
Wenn nur einige Anti-Pattern zugelassen werden, werden denen möglicherweise schnell weitere folgen und der “Tumor” beginnt zu wachsen.
Dies trifft besonders auf objektorientierte Sprachen (Java, C++, Ruby und Phyton) zu, vor allem wegen ihrer Erblast aus prozeduralen Sprachen (C, Fortran und COBOL) und weil Entwickler zu einer imperativen und prozeduralen Denkweise neigen. Unglücklicherweise.
Übrigens empfehle ich zu der Liste von Anti-Pattern [2] einige Dinge ebenfalls als schlechte Programmierlösungen [3].
Meine einzige praktische Empfehlung an dieser Stelle ist lesen und lernen. Vielleicht helfen dieses Bücher [4] oder mein eigenes [5]. Eine generelle skeptische Einstellung zur eigenen Arbeit und keine Entspannungshaltung wenn es nur funktioniert. Genauso wie bei Krebs. Je früher es diagnostiziert wird um so größer ist die Chance zu überleben.
2. Unverfolgte Änderungen
Bei einem Blick auf die commit history sollte man in der Lage sein für jede einzelne Änderung sagen zu können was geändert wurde, wer die Änderung vorgenommen hat und warum die Änderung statt gefunden hat. Es sollte nicht mehr als einige Sekunden benötigen um diese drei Fragen zu beantworten. In den meisten Projekten ist das nicht der Fall. Hier sind einige praktische Vorschläge:
Benutze stets Tickets: Ganz gleich wie klein das Projekt oder das Team ist, selbst wenn es nur eine Person umfasst. Erzeugt stets Tickets (Z. B. GitHub Issues) für jedes Problem welches gelöst wird. Erläutert das Problem kurz im Ticket und dokumentiert die Lösungsansätze. Das Ticket sollte als temporäres Sammelbecken für alle Informationen die sich auf das Problem beziehen dienen. Alles was in Zukunft dazu beitragen kann die paar „komischen“ commits zu verstehen sollte in dem Ticket veröffentlicht werden.
Referenzieren von Tickets in den Commits: Unnötig zu erwähnen ist das jeder Commit eine Beschreibung (Message) haben muss. Commits ohne Beschreibung gehören zu einer sehr unsauberen Arbeitsweise, die ich hier nicht mehr ausführen muss. Allerdings eine saloppe Beschreibung wird den Ansprüchen ebenfalls nicht gerecht. So sollte die Beschreibung stets mit der Ticketnummer beginnen, an der gerade gearbeitet wurde. GitHub beispielsweise verknüpft automatisch Commits mit den zugehörigen Tickets um die Nachverfolgbarkeit von Änderungen zu gewährleisten.
Nicht alles löschen: Git ermöglicht sogenannte „forched“ push, welche den gesamten remote Branch überschreiben.Dies ist nur ein Beispiel wie die Entwicklungshistorie zerstört werden kann. Oft habe ich beobachten können wie Leute ihre Kommentare in GitHub gelöscht haben, um die Tickets zu bereinigen. Das ist schlichtweg falsch. Lösche niemals alles. Behaltet eure Historie ganz gleich wie schlecht oder unaufgeräumt sie erscheinen mag.
3. Ad Hoc Releases
Jedes Stück Software muss vor einer Auslieferung zum Endkunden paketiert werden. Handelt es sich um eine Java Bibliothek ist das Paketformat eine .jar Datei die in die üblichen Repositorien abgelegt wurde. Ist es eine Webapplikation muss sie auf eine Plattform installiert werden. Gleich wie groß oder klein das Produkt ist es existiert eine Standartprozedur für testen, paketieren und ausliefern.
Eine optimale Lösung könnte eine Automatisierung dieser Vorgänge sein. Dies ermöglicht eine Ausführung über die Kommandozeile mit einer einfachen Anweisung.
$ ./release.sh...DONE (took 98.7s)
Die meisten Projekte sind sehr weit entfernt von solch einem Ansatz. Ihr Releaseansatz beinhaltet einige Magie. Die Leute welche dafür verantwortlich sind, auch bekannt als DevOps, müssen lediglich einige Knöpfe drücken, irgendwo einloggen und Metriken prüfen et Cetera. Solch ein Ad Hoc Releaseprozess ist ein sehr typisches Zeichen für die gesamte Software Entwicklungsindustrie.
Ich habe einige praktische Ratschläge zu geben: automatisiert. Ich verwende rultor.com dafür, aber es steht natürlich frei jedes beliebe andere Werkzeug dafür einzusetzen. Das einzig wichtige ist das der gesamte Prozess vollständig automatisiert ist und von der Kommandozeile ausgeführt werden kann.
4. Freiwillige statische Analyse
Statische Analyse [6] ist das, was den Quelltext besser aussehen lässt. Implizit sind wir bei dem Vorgang dazu eingeladen den Code auch effektiver zu machen. Dies gelingt allerdings nur wenn das gesamte Team dazu angehalten ist den Vorgaben der statischen Analysewerkzeuge zu folgen. Ich schrieb bereits darüber in [7]. Für Java Projekte hab ich qulice.com und für Ruby Projekte rubocop verwendet. Es gibt sehr viele ähnliche Werkzeuge für nahezu jede Programmiersprache.
Jedes Tool kann verwendet werden, solange es für alle Verpflichtend ist. In vielen Projekten in denen statische Analyse in Verwendung kommt, erzeugen die Entwickler lediglich aufgehübschte Reports und behalten ihre alten Programmier-Gewohnheiten bei. Solche freiwilligen Ansätze bringen keine Verbesserungen für das Projekt. Sie erzeugen lediglich eine Illusion von Qualität.
Mein Rat ist, dass die statische Analyse ein verpflichtender Schritt der Deployment Pipline ist. Ein Build kann nur dann erfolgreich sein, wenn keine der statischen Regeln verletzt wurden.
5. Unbekannte Testabdeckung
Einfach ausgerückt bedeutet Testabdeckung in welchen Grad die Software durch Unit- oder Integrationstests getestet wurde. Je höher die Testabdeckung ist, us so mehr Code wurde durch die Testfälle ausgeführt. Offensichtlich ist eine hohe Abdeckung eine gute Sache.
Wie immer kennen viele Entwickler den Grad ihre Testabdeckung nicht. Sie messen diese Metrik einfach nicht. Vielleicht haben sie einige Testfälle aber niemand vermag zu sagen wie tief diese die Software überprüfen und welche Teile nicht getestet wurden. Diese Situation ist weitaus schlimmer als eine niedrige Testabdeckung welche jedem bekannt ist.
Eine hohe Testabdeckung ist keine Garantie für gute Qualität, das ist offensichtlich. Aber eine unbekannte Testabdeckung ist ein eindeutiger Indikator von Wartbarkeitsproblemen. Wenn eine neuer Entwickler in das Projekt integriert wird, sollte er in der Lage sein einige Änderungen vorzunehmen und sehen wie die Testabdeckung sich dadurch verändert. Idealerweise sollte wie Testabdeckung auf gleiche Weise wie statische Analyse überprüft werden. Der Buld sollte fehlschlagen wenn die Voreinstellung unterschritten wird. Idealerweise beträgt die Testabdeckung um die 80%.
6. Nonstop Entwicklung
Was ich mit nonstop meine ist Entwicklung ohne Meilensteine und Releases. Egal welche Art von Software implementiert wird, sie muss Released und die Ergebnisse regelmäßig visualisiert werden. Ein Projekt ohne eine eindeutige Releasehistorie ist ein unwartbares Chaos.
Der Grund dafür ist, das Wartbarkeit nur dann möglich ist, wenn der Quelltext gelesen und auch verstanden wurde.
Wenn ich einen Blick auf die Sourcen werfe, den zugehörigen Commits und der Release Historie sollte ich in der Lage sein zu sagen was die Intension des Autors war. Was passierte im Projekt vor einem Jahr? Wie steht es mit dem aktuellen Status? Wie sind die künftigen Schritte geplant? Alle diese Informationen müssen Bestandteil des Quelltextes sein und noch viel wichtiger, in der Git Historie.
Git Tags und GitHub Release Notes sind zwei wirkungsvolle Instrumente die mir diese Informationen zu Verfügung stellen. Nutze sie in vollem Umfang. Ebenso sollte nicht vergessen werden, das jede binäre Version des Produktes als ständiger Download verfügbar sein muss. Das bedeutet das ich in der Lage sein sollt die Version 0.1.3 herunter zu aden und zu testen, selbst wenn das Projekt bereits an der Version 3.4 arbeitet.
7. Undokumentierte Interfaces
Jede Software hat Schnittstellen, die verwendet werden sollten. Handelt es sich um eine Ruby gem, so existieren Klassen und Methoden die von Endanwendern Verwendung finden. Geht es um eine Webapplikation so gibt es Webseiten welche von einem Endbenutzer aufgerufen werden um mit der Anwendung zu interagieren. Jedes Software Projekt hat also ein Interface welches ausführlich beschreiben werden muss.
Wie mit den andern Punkten, welche bereits erwähnt wurden handelt es sich hierbei auch um Wartbarkeit. Als neuer Programmierer in einem Projekt beginnt die Einarbeitung bei den Interfaces. Jeder sollte daher verstehen was die Aufgabe des Interfaces ist und wie es benutzt werden kann.
Ich spreche von der Dokumentation für die Benutzer, nicht für Entwickler. Im allgemeinen bin ich gegen Dokumentation innerhalb der Software. An dieser Stelle stimme ich vollständig mit dem Agilen Manifest [7] überein. Funktionierende Anwendungen sind wichtiger als ausschweifende Dokumentation. Aber das meint nicht das Referenzieren auf eine externe Dokumentation welche für die Anwender gedacht ist.
Endanwender Interaktion mit der Anwendung muss sauber dokumentiert werden.
Handelt es sich um eine Bibliothek, so sind die Anwender Entwickler welche das Produkt verwenden und es nicht durch eigenen Code erweitern. Die Nutzung erfolgt ausschließlich als Black Box.
Diese Kriterien verwenden wir um Open Source Projekte für unseren Award [8] zu evaluieren.
im Original auf Englisch auch auf DZone 04.2020 veröffentlicht
Nachdem die Gang Of Four (GOF) Erich Gamma, Richard Helm, Ralph Johnson und John Vlissides das Buch Design Patterns: Elements of Reusable Object-Oriented Software (Elemente wiederverwendbarer objektorientierter Software), wurde das Erlernen der Beschreibung von Problemmustern und deren Lösungen in fast allen Bereichen der Softwareentwicklung populär. Ebenso populär wurde das Erlernen der Beschreibung von Don’ts und Anti-Patterns.
In Publikationen, die sich mit den Konzepten der Entwurfsmuster und Anti-Pattern befassen, finden wir hilfreiche Empfehlungen für Softwaredesign, Projektmanagement, Konfigurationsmanagement und vieles mehr. In diesem Artikel möchte ich meine Erfahrungen im Umgang mit Versionsnummern für Software-Artefakte weitergeben.
Die meisten von uns sind bereits mit einer Methode namens semantische Versionierung vertraut, einem leistungsstarken und leicht zu erlernenden Regelwerk dafür, wie Versionsnummern strukturiert sein sollten und wie die einzelnen Segmente zu inkrementieren sind.
Beispiel für eine Versionsnummerierung:
Major: Inkompatible API-Änderungen.
Minor: Hinzufügen neuer Funktionen.
Patch: Fehlerbehebungen und Korrekturen.
Label: SNAPSHOT zur Kennzeichnung des Status “in Entwicklung”.
Eine inkompatible API-Änderung liegt dann vor, wenn eine von außen zugängliche Funktion oder Klasse gelöscht oder umbenannt wurde. Eine andere Möglichkeit ist eine Änderung der Signatur einer Methode. Das bedeutet, dass der Rückgabewert oder die Parameter gegenüber der ursprünglichen Implementierung geändert wurden. In diesen Fällen ist es notwendig, das Major-Segment der Versionsnummer zu erhöhen. Diese Änderungen stellen für API-Kunden ein hohes Risiko dar, da sie ihren eigenen Code anpassen müssen.
Beim Umgang mit Versionsnummern ist es auch wichtig zu wissen, dass 1.0.0 und 1.0 gleichwertig sind. Dies hat mit der Anforderung zu tun, dass die Versionen einer Softwareversion eindeutig sein müssen. Wenn dies nicht der Fall ist, ist es unmöglich, zwischen Artefakten zu unterscheiden. In meiner beruflichen Praxis war ich mehrfach an Projekten beteiligt, bei denen es keine klar definierten Prozesse für die Erstellung von Versionsnummern gab. Dies hatte zur Folge, dass das Team die Qualität des Artefakts sicherstellen musste und sich nicht mehr sicher war, mit welcher Version des Artefakts es sich gerade befasste.
Der größte Fehler, den ich je gesehen habe, war die Speicherung der Version eines Artefakts in einer Datenbank zusammen mit anderen Konfigurationseinträgen. Die korrekte Vorgehensweise sollte sein: die Version innerhalb des Artefakts so zu platzieren, dass niemand nach einem Release diese von außen ändern kann. Die Falle, in die man sonst tappt, ist der Prozess, wie man die Version nach einem Release oder Neuinstallation aktualisiert.
Vielleicht haben Sie eine Checkliste für alle manuellen Tätigkeiten während eines Release. Aber was passiert, nachdem eine Version in einer Testphase installiert wurde und aus irgendeinem Grund eine andere Version der Anwendung eneut installiert werden muss? Ist Ihnen noch bewusst, dass Sie die Versionsnummer manuell in der Datenbank ändern müssen? Wie finden Sie heraus, welche Version installiert ist, wenn die Informationen in der Datenbank nicht stimmen?
Die richtige Version in dieser Situation zu finden, ist eine sehr schwierige Aufgabe. Aus diesem Grund haben gibt es die Anforderung, die Version innerhalb der Anwendung zu halten. Im nächsten Schritt werden wir einen sicheren und einfachen Weg aufzeigen, wie man dieses Problem voll automatisiert lösen kann.
Die Voraussetzung ist eine einfache Java-Bibliothek die mit Maven gebaut wird. Standardmäßig wird die Versionsnummer des Artefakts in der POM notiert. Nach dem Build-Prozess wird unser Artefakt erstellt und wie folgt benannt: artifact-1.0.jar oder ähnlich. Solange wir das Artefakt nicht umbenennen, haben wir eine gute Möglichkeit, die Versionen zu unterscheiden. Selbst nach einer Umbenennung kann mit einem einfachen Trick nach einem Unzip des Archives im META-INF-Ordner der richtige Wert gefunden werden.
Wenn Sie die Version in einer Poroperty oder Klasse fest einkodiert haben, würde das auch funktionieren, solange Sie nicht vergessen diese immer aktuell zu halten. Vielleicht müssen Sie dem Branching und Merging in SCM Systemen wie Git besondere Aufmerksamkeit schenken, um immer die korrekte Version in Ihrer Codebasis zu haben.
Eine andere Lösung ist die Verwendung von Maven und dem Tokenreplacement. Bevor Sie dies in Ihrer IDE ausprobieren, sollten Sie bedenken, dass Maven zwei verschiedene Ordner verwendet: Sources und Ressourcen. Die Token-Ersetzung in den Quellen wird nicht richtig funktionieren. Nach einem ersten Durchlauf ist Ihre Variable durch eine feste Zahl ersetzt und verschwunden. Ein zweiter Durchlauf wird daher fehlschlagen. Um Ihren Code für die Token-Ersetzung vorzubereiten, müssen Sie Maven als erstes im Build-Lifecycle konfigurieren:
Nach diesem Schritt müssen Sie die Property ${project.version} aus dem POM kennen. Damit können Sie eine Datei mit dem Namen version.property im Verzeichnis resources erstellen. Der Inhalt dieser Datei besteht nur aus einer Zeile: version=${project.version}. Nach einem Build finden Sie in Ihrem Artefakt die version.property mit der gleichen Versionsnummer, die Sie in Ihrem POM verwendet haben. Nun können Sie eine Funktion schreiben, die die Datei liest und diese Property verwendet. Sie können das Ergebnis zum Beispiel in einer Konstante speichern, um es in Ihrem Programm zu verwenden. Das ist alles, was Sie tun müssen!
Zu der Erkenntnis, dass Menschen Projekte machen, gelangt man nicht erst durch die Lektüre von Tom De Marcos Büchern. Aber was hat sich in den letzten Jahrzehnten tatsächlich in der professionellen Software Entwicklung getan? Trotz der vielen neuen Innovationen und Methodiken hat sich augenscheinlich nur wenig bewegt. Die Klagelieder aus den Unternehmen summen nach wie vor die gleiche Melodie.
(c) 2017 Marco Schulz, Java PRO Ausgabe 2, S.51-53
Stellen wir uns bei all dem Wandel einmal eine essentielle Frage: Kann ein Softwareprojekt heute noch erfolgreich sein, wenn es nicht auf Methoden wie Scrum setzt oder die neuesten Innovationen verwendet? Anwendungen werden Dank leistungsfähigerer Maschinen zunehmend komplexer, so dass diese nicht mehr von einzelnen Personen in ihrer Gänze überblickt werden können. Das gute Teamarbeit ein wichtiger Bestandteil erfolgreicher Projekte ist, ist seit langem auch bei den Unternehmen angekommen. Daher zählen bei Bewerbungsgesprächen mittlerweile nicht allein harte technische Fähigkeiten. Auch ausgewogene Softskills und Kommunikationsfähigkeit sind wichtige Anforderungen bei der Auswahl von neuem Personal. Daher die provokante Behauptung, dass andere Faktoren für Projekterfolge wesentlich essentieller sind als technologische Details.
Alter Wein in neuen Schläuchen?
Ganz so einfach ist es dann doch nicht. Und nicht alles Neue macht der Mai. Aus persönlicher Erfahrung wiederholt sich die Geschichte kontinuierlich, lediglich die Protagonisten können ausgetauscht werden. Stellen wir die klassischen Modelle in einen Vergleich mit agilen Techniken, können wir nur wenige essentielle Unterschiede ausmachen. Die einzelnen Stufen wie Planung, Implementierung, Testen und Ausliefern sind wenig variabel. Ob man nun den Projektleiter als Scrum-Master bezeichnet oder Releases lieber als Sprints definiert, ist Geschmackssache. Allein ein neues Vokabular genügt allerdings nicht, um von tatsächlicher Innovation zu sprechen. Ein neues Vokabular hilft aber durchaus, sich leichter von alten und möglicherweise schlechten Gewohnheiten zu lösen. Der Ansatz von Scrum ist es, das Kommunikationsproblem in Teams zu adressieren und durch Techniken aus der Rhetorik, die gemeinsamen Ziele zu visualisieren. Kurze Entwicklungszyklen ermöglichen ein schnelles Feedback um mögliche Probleme bereits zu Beginn zu erkennen und berichtigen zu können. Auf tatsächliche Bedürfnisse zügig zu reagieren sind Kernkompetenzen eines Managers. Analysiert man in einer Retrospektive was zu Fehleinschätzungen beim Management geführt hat, ist es nicht selten die mangelnde Bereitschaft sich mit technischen Zusammenhängen auseinandersetzen zu wollen. Dies ist aber essentiell, für ein Gelingen der anvisierten Ziele. Klare Anweisungen lassen sich nur dann formulieren, wenn man deren Inhalt auch versteht. Ein sehr empfehlenswerter Titel für IT Management ist von Johanna Rothman und Esther Derby „Behind closed Doors“ welches hervorragend Motivierung, Teamentwicklung und Kommunikation bespricht.
Werfen wir einmal ein Blick in ein typisches Auftaktmeeting, wenn ein neues Projekt initiiert wird. Oft ist an dieser Stelle noch keine klare Vision vorhanden. Das wiederum hat zur Folge das schwammige Anforderungen formuliert werden. Sehr klassisch ist bei nicht funktionalen Anforderungen, dass sich alle Beteiligten einig sind, dass beispielsweise eine hohe Qualität eingehalten werden muss. Es wir schnell vergessen zu definieren, was man unter Qualität versteht und wie man dies erreichen will. Lenkt man in diesen Meetings alle Beteiligten auf die Details, fehlt oft die Bereitschaft sich diesen mit der notwendigen Sorgfalt zuzuwenden. Euphorisch benennt man fix einen Qualitätsverantwortlichen, ohne ihm die notwendige Entscheidungsgewalt zuzusprechen. Zum Thema Qualität hat sich sehr ausführlich bereits im Jahre 1976 B. W. Boehm auf knapp 14 Seiten geäußert. Eine Lösung für dieses Problem wäre es, sich zu entschließen einen hohen Wert auf Coding-Standarts zu legen. Diese Konvention ermöglicht es den einzelnen Entwicklern sich schnell in die Lösungen der Kollegen einzufinden. Es gewährleistet nicht, das die Applikation robust gegen Änderungen ist und diese über einen langen Zeitraum auch wartungsfähig bleibt. Eine Entscheidung alle diese Aspekte zu bedienen hat die Konsequenz, dass damit auch die bereitzustellenden Aufwände erhöht werden müssen. Von daher gilt es, bewusst abzuwägen was tatsächlich notwendig ist. Aber verweilen wir nicht allzu lange beim Management. Es gibt viele weitere Dinge die es lohnt ein wenig stärker auszuleuchten.
Im Gleichschritt Marsch!
Nicht alle Arbeiten zählen zu den begehrtesten Beschäftigungen, dennoch müssen sie erledigt werden. Eine gute Unterstützung findet man für solche Tätigkeiten in Automatisierungsmechanismen. Dazu muss man sich auch bewusst sein, dass eine automatisierte Lösung bei komplexen Problemen sehr aufwendig gestaltet werden kann. Die damit verbundenen Kosten können sich erst dadurch amortisieren, dass die gefundene Lösung sehr häufig eingesetzt wird oder die Anfälligkeiten für Fehler während der Ausführung massiv reduziert werden. Ein hervorragendes Beispiel für diese Thematik sind Build- und Testprozesse. Nicht das Werkzeug bestimmt das Ergebnis, sondern der Prozess definiert das zu verwendende Werkzeug. Auch an dieser Stelle überschätzt sich der Mensch hin und wieder, in dem er hochkomplexe Prozesse nicht in ihre Bestandteile zerlegt, um diese dann nacheinander abzuarbeiten. Schlägt dann ein Schritt fehl ist nur dieser Teilprozess zu wiederholen. Hierzu gab es, in unterschiedlichen persönlich erlebten Situationen des Autors, ähnliche Begebenheiten. Es war notwendig die Aussage zu entkräften, weswegen es sich bei der Wahl explizit gegen Maven und bewusst für Gradle entschieden werden sollte. Das Argument für Gradle war die Möglichkeit eines frei choreographierbaren Buil-Prozesses und die damit verbundene Flexibilität. Die Notwendigkeit einer Build-Choreographie kann ein wichtiger Indikator für eine mangelhafte Architektur sein. Fehlende Kapselung und dadurch implizierte Abhängigkeiten sind die üblichen Verdächtigen. Die strikten Konventionen von Maven reduzieren hingegen das Aufkommen von unlesbaren Build-Skripten, die kaum oder nur mit erheblichem Aufwand gewartet werden können. Es ist nicht immer förderlich, volles Vertrauen an die Verantwortlichen zu delegieren, in der Absicht, dass diese optimale Ergebnisse produzieren. Zuviel Freiheit führt auch schnell zu Anarchie. In diesem Zusammenhang wäre das Argument für die Verwendung von Gradle, bereits einen Experten für diese Technologie im Hause zu haben, so schwergewichtig, dass wenig Spielräume für eine andere Wahl offen stünden.
Auch die Erstellung von Testfällen ist ein Kapitel für sich. Es grenzt schon an ein Wunder, wenn überhaupt Testfälle existieren. Wenn diese dann auch noch eine hohe Testabdeckung erzielen, könnte man meinen einen Großteil möglicher Risiken minimiert zu haben. Dass Testen nicht gleich Testen ist, skizziert die folgende Überlegung: Sehr wichtig ist zu wissen, dass das Bestehen der Testfälle keine Fehlerfreiheit garantiert. Es wird lediglich garantiert, dass die Anwendung sich entsprechend den Vorgaben der Testfälle verhält. Hierzu ist es interessant zu wissen, dass für IT-Projekte der NASA sämtliche Compiler-Meldungen für selbst entwickelte Software, die sich in Produktion befindet, behoben sein müssen. Aber auch die Aussagekraft von Testfällen lässt sich etwas ausführlicher betrachten. Die zyklomatische Komplexität nach McCabe gibt einen guten Hinweis, wie viele Testfälle für eine Methode benötigt werden. Veranschaulichen wir die Zusammenhänge an einem kleinen Beispiel. Ein Validator prüft anhand eines regulären Ausdrucks (Regex) mit der Methode validate(), ob es sich bei der Benutzereingabe um ein korrektes 24-Stunden-Format der Uhrzeit handelt. Dabei werden ausschließlich die Stunden und Minuten in zweistelliger Notation (hh:mm) angenommen. Es besteht nun die Möglichkeit einen einzigen Testfall für den regulären Ausdruck der Uhrzeit zu schreiben. Schlägt dieser Test fehl, muss der Entwickler den vorhandenen Testfall analysieren um das Problem zu identifizieren. Genauso wenig sagt die Methode testUhrzeit24hFormat() über die tatsächlichen durchgeführten Tests etwas aus. So hat man möglicherweise nicht immer im Fokus, dass Werte wie 24:00 oder 00:60 unzulässig sind, hingegen 00:00 und 23:59 gültige Einträge darstellen. Splittet man den Testfall beispielsweise in die Teile testMinuten und testStunden, so erkennt man schnell die tatsächlichen Schranken. Dieser Formalismus gestattet es zudem fehlgeschlagene Testfälle schneller bewerten zu können. Die Kombination mit dem Framework jGiven ermöglicht es deskriptive Testszenarien zu formulieren, sodass nachgelagerte manuelle Akzeptanztest weniger aufwendig gestaltet werden müssen.
Wir messen, weil wir können
Die Vermessung der Welt ist nicht allein den rein physikalischen Größen vorbehalten. Auch für Softwareprojekte bilden Metriken eine nützliche Informationsquelle. Wie bereits erläutert ist die zyklomatische Komplexität ein guter Anhaltspunkt für die Bewertung von Testfällen. Auch die klassischen Lines-of-Code (LoC) sagen einiges über die Größe eines Projektes aus. Was bei all dem Zahlenwerk oft wenig beachtet wird, sind die tatsächlichen Points-of-Intrests (PoI). Sicher kann man Äpfel mit Birnen vergleichen. Aber der Nutzen bleibt etwas fragwürdig wenn man keinen geeigneten Kontext definiert. Auch an dieser Stelle ist es wichtig sich nicht mit einer Informationsflut an Daten zu überfordern. So ist es hilfreich, die Projektentwicklung der einzelnen Release Milestones zu dokumentieren und dann zu vergleichen. Auch die Vergleichbarkeit unterschiedlicher Projekte führt zu neuen Erkenntnissen. Dabei ist es aber nicht förderlich ein Projekt, welches bereits 10 Jahre Entwicklung beschritten hat, mit einer kleinen Hilfsbibliothek zu vergleichen. Auch die Repräsentation der ermittelten Informationen ist ein nicht zu vernachlässigendes Detail. Eine grafische Darstellung lässt die Zusammenhänge leichter fassen. So ist die reine Darstellung der LoC als nackte Zahl nett zu wissen, aber eine Bewertung gestaltet sich auf diese Weise eher schwer. Ein kumulierter Chart über die Entwicklung der LoC zu den einzelnen Releases vermittelt dagegen ein recht deutliches Bild. Dies lässt sich weiter befüllen mit der Anzahl der Klassen, Interfaces, Packages und JavaDocs und all dies in Relation zur Speichergröße des fertigen Artefaktes zu setzen. Der Einsatz hochkomplexer Werkzeuge kann durch ein geeignetes Tabellenkalkulationsprogramm und Methoden des Projekt-Controllings ohne weiteres ersetzt werden. Ein Skript, das die notwendigen Rohdaten einsammelt, kann von der Entwicklungsabteilung schnell bereitgestellt werden ohne, dass ein überfrachteter Werkzeugkasten den man mit sich herum tragen muss, zu „schweren Rückenproblemen“ führt.
Informationsdschungel
Ein weiterer Blick in den Werkzeugkasten bringt nicht selten verstaubte Infrastruktur zutage, die den Anschein erweckt als reiner Selbstzweck zu fungieren. Das Unternehmens-Wiki, bei dem die meisten Einträge aus weniger als 100 Zeichen bestehen sowie eine Navigation nur vermutet werden kann, ist leider die traurige die Regel. Aussagen zum Daily-Meeting wie „Ich bin Heiko und kümmere mich auch heute wieder um die Suchfunktion“ erinnern eher an eine Selbsthilfegruppe. Das Ganze wird dann noch durch SCM-Logeinträge (SCM ist ein Tool zur Kommentierung von Issues) wie „JIRA-KM-100 update Build-Skripte“ dekoriert. Gute Kommunikation ist mehr als sich seinen Mitmenschen mitzuteilen. Reflektierte Aussagen unterstützen uns bei der Bewältigung unserer täglichen Aufgaben. Sie strukturieren zugleich unser Denken. Wenn wir beim morgendlichen Treffen mit den Kollegen hingegen sagen „Für das Erzeugen des Suchindexes implementiere ich heute die Abfragen über die Keywords in den Content-Tabellen, sodass ich morgen bereits einige Testfälle formulieren kann“, kurz und auf den Punkt gebracht, dann sind die Kollegen informiert. Ein präziser Kommentar im SCM „JIRAKM-100 Hinzufügen der Lucene-Abhängigkeiten für die Suche“ gibt schnell Aufschluss über die vorgenommenen Arbeiten ohne, dass man erst den entsprechenden Task im Issue-Managment öffnen muss, um zu sehen welche Änderungen vorgenommen wurden. Bereits diese kleinen Aufmerksamkeiten in unserer Kommunikation bewirken einen enormen Anschub in die Motivation des gesamten Teams. Jeder einzelne empfindet sich so wesentlich mehr wertgeschätzt. Funktionierende und aktuelle Anleitungen über das Einrichten des Arbeitsplatzes, Hinweise mit Beispielen zum Schreiben von Kommentaren für SCM-Commits regen die Kollegen zum Mitmachen an. Der Mehrwert einer solchen Unternehmenskultur beschränkt sich nicht einzig auf einen funktionierenden Informationsaustausch. Das höhere Ziel dieser Bestrebungen ist auf eine angenehme Weise, die Produktivität zu steigern, ohne stetig Druck ausüben zu müssen.
Lessons Learned
Wie wir sehen konnten, genügt es nicht sich allein auf eine gute Methodik wie Scrum zu verlassen, um sich von den notwendigen Vorbereitungen befreien zu können. Der Wille allein, etwas Hervorragendes zu erschaffen, ist nicht ausschlaggebend für beste Resultate. Vor den Erfolg ist stets Fleiß zu setzen. Bevor man sich in Details verliert ist es unerlässlich, das große Ganze sehen zu können. Erst wenn alle Beteiligten die gleiche Vision teilen, können sie gemeinsam in die Mission starten. Anhand der beschriebenen Beispiele kann man gut nachvollziehen, dass die vielen neuen Techniken erhebliche Möglichkeiten bieten. Diese Chancen lassen sich allerdings nur dann nutzen, wenn man zuerst die notwendigen Grundlagen tief verinnerlicht hat.
Auch wenn zur Qualitätssteigerung der Software- Projekte in den letzten Jahren ein erheblicher Mehraufwand für das Testen betrieben wurde [1], ist der Weg zu kontinuierlich wiederholbaren Erfolgen keine Selbstverständlichkeit. Stringentes und zielgerichtetes Management aller verfügbaren Ressourcen war und ist bis heute unverzichtbar für reproduzierbare Erfolge.
(c) 2016 Marco Schulz, Java aktuell Ausgabe 4, S.14-19
Es ist kein Geheimnis, dass viele IT-Projekte nach wie vor ihre liebe Not haben, zu einem erfolgreichen Abschluss zu gelangen. Dabei könnte man durchaus meinen, die vielen neuen Werkzeuge und Methoden, die in den letzten Jahren aufgekommen sind, führten wirksame Lösungen ins Feld, um der Situation Herr zu werden. Verschafft man sich allerdings einen Überblick zu aktuellen Projekten, ändert sich dieser Eindruck.
Der Autor hat öfter beobachten können, wie diese Problematik durch das Einführen neuer Werkzeuge beherrscht werden sollte. Nicht selten endeten die Bemühungen in Resignation. Schnell entpuppte sich die vermeintliche Wunderlösung als schwergewichtiger Zeiträuber mit einem enormen Aufwand an Selbstverwaltung. Aus der anfänglichen Euphorie aller Beteiligten wurde schnell Ablehnung und gipfelte nicht selten im Boykott einer Verwendung. So ist es nicht verwunderlich, dass erfahrene Mitarbeiter allen Veränderungsbestrebungen lange skeptisch gegenüberstehen und sich erst dann damit beschäftigen, wenn diese absehbar erfolgreich sind. Aufgrund dieser Tatsache hat der Autor als Titel für diesen Artikel das provokante Zitat von Grady Booch gewählt, einem Mitbegründer der UML.
Oft wenden Unternehmen zu wenig Zeit zum Etablieren einer ausgewogenen internen Infrastruktur auf. Auch die Wartung bestehender Fragmente wird gern aus verschiedensten Gründen verschoben. Auf Management-Ebene setzt man lieber auf aktuelle Trends, um Kunden zu gewinnen, die als Antwort auf ihre Ausschreibung eine Liste von Buzzwords erwarten. Dabei hat es Tom De Marco bereits in den 1970er-Jahren ausführlich beschrieben [2]: Menschen machen Projekte (siehe Abbildung 1).
Wir tun, was wir können, aber können wir etwas tun?
Das Vorhaben, trotz bester Absichten und intensiver Bemühungen ein glückliches Ende finden, ist leider nicht die Regel. Aber wann kann man in der Software-Entwicklung von einem gescheiterten Projekt sprechen? Ein Abbruch aller Tätigkeiten wegen mangelnder Erfolgsaussichten ist natürlich ein offensichtlicher Grund, in diesem Zusammenhang allerdings eher selten. Vielmehr gewinnt man diese Erkenntnis während der Nachbetrachtung abgeschlossener Aufträge. So kommen beispielsweise im Controlling bei der Ermittlung der Wirtschaftlichkeit Schwachstellen zutage.
Gründe für negative Ergebnisse sind meist das Überschreiten des veranschlagten Budgets oder des vereinbarten Fertigstellungstermins. Üblicherweise treffen beide Bedingungen gleichzeitig zu, da man der gefährdeten Auslieferungsfrist mit Personal-Aufstockungen entgegenwirkt. Diese Praktik erreicht schnell ihre Grenzen, da neue Teammitglieder eine Einarbeitungsphase benötigen und so die Produktivität des vorhandenen Teams sichtbar reduzieren. Einfach zu benutzende Architekturen und ein hohes Maß an Automatisierung mildern diesen Effekt etwas ab. Hin und wieder geht man auch dazu über, den Auftragnehmer auszutauschen, in der Hoffnung, dass neue Besen besser kehren.
Wie eine fehlende Kommunikation, unzureichende Planung und schlechtes Management sich negativ auf die äußere Wahrnehmung von Projekten auswirkt, zeigt ein kurzer Blick auf die Top-3-Liste der in Deutschland fehlgeschlagenen Großprojekte: Berliner Flughafen, Hamburger Elbphilharmonie und Stuttgart 21. Dank ausführlicher Berichterstattung in den Medien sind diese Unternehmungen hinreichend bekannt und müssen nicht näher erläutert werden. Auch wenn die angeführten Beispiele nicht aus der Informatik stammen, finden sich auch hier die stets wiederkehrenden Gründe für ein Scheitern durch Kostenexplosion und Zeitverzug.
Abbildung 1: Problemlösung – „A bisserl was geht immer“, Monaco Franze
Der Wille, etwas Großes und Wichtiges zu erschaffen, allein genügt nicht. Die Verantwortlichen benötigen auch die notwendigen fachlichen, planerischen, sozialen und kommunikativen Kompetenzen, gepaart mit den Befugnissen zum Handeln. Luftschlösser zu errichten und darauf zu warten, dass Träume wahr werden, beschert keine vorzeigbaren Resultate.
Große Erfolge werden meist dann erzielt, wenn möglichst wenige Personen bei Entscheidungen ein Vetorecht haben. Das heißt nicht, dass man Ratschläge ignorieren sollte, aber auf jede mögliche Befindlichkeit kann keine Rücksicht genommen werden. Umso wichtiger ist es, wenn der Projektverantwortliche die Befugnis hat, seine Entscheidung durchzusetzen, dies jedoch nicht mit aller Härte demonstriert.
Es ist völlig normal, wenn man als Entscheidungsträger nicht sämtliche Details beherrscht. Schließlich delegiert man die Umsetzung an die entsprechenden Spezialisten. Dazu ein kurzes Beispiel: Als sich in den frühen 2000er-Jahren immer bessere Möglichkeiten ergaben, größere und komplexere Web-Anwendungen zu erstellen, kam in Meetings oft die Frage auf, mit welchem Paradigma die Anzeigelogik umzusetzen sei. Die Begriffe „Multi Tier“, „Thin Client“ und „Fat Client“ dominierten zu dieser Zeit die Diskussionen der Entscheidungsgremien. Dem Auftraggeber die Vorteile verschiedener Schichten einer verteilten Web-Applikation zu erläutern, war die eine Sache. Einem technisch versierten Laien aber die Entscheidung zu überlassen, wie er auf seine neue Applikation zugreifen möchte – per Browser („Thin Client“) oder über eine eigene GUI („Fat Client“) –, ist schlicht töricht. So galt es in vielen Fällen, während der Entwicklung auftretende Missverständnisse auszuräumen. Die schmalgewichtige Browser-Lösung entpuppte sich nicht selten als schwer zu beherrschende Technologie, da Hersteller sich selten um Standards kümmerten. Dafür bestand üblicherweise eine der Hauptanforderungen darin, die Applikation in den gängigsten Browsern nahezu identisch aussehen zu lassen. Das ließ sich allerdings nur mit erheblichem Mehraufwand umsetzen. Ähnliches konnte beim ersten Hype der Service-orientierten Architekturen beobachtet werden.
Die Konsequenz aus diesen Beobachtungen zeigt, dass es unverzichtbar ist, vor dem Projektstart eine Vision zu erarbeiten, deren Ziele auch mit dem veranschlagten Budget übereinstimmen. Eine wiederverwendbare Deluxe-Variante mit möglichst vielen Freiheitsgraden erfordert eine andere Herangehensweise als eine „We get what we need“-Lösung. Es gilt, sich weniger in Details zu verlieren, als das große Ganze im Blick zu halten.
Besonders im deutschsprachigen Raum fällt es Unternehmen schwer, die notwendigen Akteure für eine erfolgreiche Projektumsetzung zu finden. Die Ursachen dafür mögen recht vielfältig sein und könnten unter anderem darin begründet sein, dass Unternehmen noch nicht verstanden haben, dass Experten sich selten mit schlecht informierten und unzureichend vorbereiteten Recruitment-Dienstleistern unterhalten möchten.
Getting things done!
Erfolgreiches Projektmanagement ist kein willkürlicher Zufall. Schon lange wurde ein unzureichender Informationsfluss durch mangelnde Kommunikation als eine der negativen Ursachen identifiziert. Vielen Projekten wohnt ein eigener Charakter inne, der auch durch das Team geprägt ist, das die Herausforderung annimmt, um gemeinsam die gestellte Aufgabe zu bewältigen. Agile Methoden wie Scrum [3], Prince2 [4] oder Kanban [5] greifen diese Erkenntnis auf und bieten potenzielle Lösungen, um IT-Projekte erfolgreich durchführen zu können.
Gelegentlich ist jedoch zu beobachten, wie Projektleiter unter dem Vorwand der neu eingeführten agilen Methoden die Planungsaufgaben an die zuständigen Entwickler zur Selbstverwaltung übertragen. Der Autor hat des Öfteren erlebt, wie Architekten sich eher bei Implementierungsarbeiten im Tagesgeschäft gesehen haben, anstatt die abgelieferten Fragmente auf die Einhaltung von Standards zu überprüfen. So lässt sich langfristig keine Qualität etablieren, da die Ergebnisse lediglich Lösungen darstellen, die eine Funktionalität sicherstellen und wegen des Zeit- und Kostendrucks nicht die notwendigen Strukturen etablieren, um die zukünftige Wartbarkeit zu gewährleisten. Agil ist kein Synonym für Anarchie. Dieses Setup wird gern mit einem überfrachteten Werkzeugkasten voller Tools aus dem DevOps-Ressort dekoriert und schon ist das Projekt scheinbar unsinkbar. Wie die Titanic!
Nicht ohne Grund empfiehlt man seit Jahren, beim Projektstart allerhöchstens drei neue Technologien einzuführen. In diesem Zusammenhang ist es auch nicht ratsam, immer gleich auf die neuesten Trends zu setzen. Bei der Entscheidung für eine Technologie müssen im Unternehmen zuerst die entsprechenden Ressourcen aufgebaut sein, wofür hinreichend Zeit einzuplanen ist. Die Investitionen sind nur dann nutzbringend, wenn die getroffene Wahl mehr als nur ein kurzer Hype ist. Ein guter Indikator für Beständigkeit sind eine umfangreiche Dokumentation und eine aktive Community. Diese offenen Geheimnisse werden bereits seit Jahren in der einschlägigen Literatur diskutiert.
Wie geht man allerdings vor, wenn ein Projekt bereits seit vielen Jahren etabliert ist, aber im Sinne des Produkt-Lebenszyklus ein Schwenk auf neue Techniken unvermeidbar wird? Die Gründe für eine solche Anstrengung mögen vielseitig sein und variieren von Unternehmen zu Unternehmen. Die Notwendigkeit, wichtige Neuerungen nicht zu verpassen, um im Wettbewerb weiter bestehen zu können, sollte man nicht zu lange hinauszögern. Aus dieser Überlegung ergibt sich eine recht einfach umzusetzende Strategie. Aktuelle Versionen werden in bewährter Tradition fortgesetzt und erst für das nächste beziehungsweise übernächste Major-Release wird eine Roadmap erarbeitet, die alle notwendigen Punkte enthält, um einen erfolgreichen Wechsel durchzuführen. Dazu erarbeitet man die kritischen Punkte und prüft in kleinen Machbarkeitsstudien, die etwas anspruchsvoller als ein „Hallo Welt“- Tutorial sind, wie eine Umsetzung gelingen könnte. Aus Erfahrung sind es die kleinen Details, die das Krümelchen auf der Waagschale sein können, um über Erfolg oder Misserfolg zu entscheiden.
Bei allen Bemühungen wird ein hoher Grad an Automatisierung angestrebt. Gegenüber stetig wiederkehrenden, manuell auszuführenden Aufgaben bietet Automatisierung die Möglichkeit, kontinuierlich wiederholbare Ergebnisse zu produzieren. Dabei liegt es allerdings in der Natur der Sache, dass einfache Tätigkeiten leichter zu automatisieren sind als komplexe Vorgänge. Hier gilt es, zuvor die Wirtschaftlichkeit der Vorhaben zu prüfen, sodass Entwickler nicht gänzlich ihrem natürlichen Spieltrieb frönen und auch unliebsame Tätigkeiten des Tagesgeschäfts abarbeiten.
Wer schreibt, der bleibt
Dokumentation, das leidige Thema, erstreckt sich über alle Phasen des Software-Entwicklungsprozesses. Ob für API-Beschreibungen, das Benutzer-Handbuch, Planungsdokumente zur Architektur oder erlerntes Wissen über optimales Vorgehen – das Beschreiben zählt nicht zu den favorisierten Aufgaben aller beteiligten Protagonisten. Dabei lässt sich oft beobachten, dass anscheinend die landläufige Meinung vorherrscht, dicke Handbücher ständen für eine umfangreiche Funktionalität des Produkts. Lange Texte in einer Dokumentation sind jedoch eher ein Qualitätsmangel, der die Geduld des Lesers strapaziert, weil dieser eine präzise auf den Punkt kommende Anleitung erwartet. Stattdessen erhält er schwammige Floskeln mit trivialen Beispielen, die selten problemlösend sind.
Abbildung 2: Test Coverage mit Cobertura
Diese Erkenntnis lässt sich auch auf die Projekt-Dokumentation übertragen und wurde unter anderem von Johannes Sidersleben [6] unter der Metapher über viktorianische Novellen ausführlich dargelegt. Hochschulen haben diese Erkenntnisse bereits aufgegriffen. So hat beispielsweise die Hochschule Merseburg den Studiengang „Technische Redaktion“ [7] etabliert. Es bleibt zu hoffen, zukünftig mehr Absolventen dieses Studiengangs in der Projekt-Landschaft anzutreffen.
Bei der Auswahl kollaborativer Werkzeuge als Wissensspeicher ist immer das große Ganze im Blick zu halten. Erfolgreiches Wissensmanagement lässt sich daran messen, wie effizient ein Mitarbeiter die gesuchte Information findet. Die unternehmensweite Verwendung ist aus diesem Grund eine Managemententscheidung und für alle Abteilungen verpflichtend.
Informationen haben ein unterschiedliches Naturell und variieren sowohl in ihrem Umfang als auch bei der Dauer ihrer Aktualität. Daraus ergeben sich verschiedene Darstellungsformen wie Wiki, Blog, Ticketsystem, Tweets, Foren oder Podcasts, um nur einige aufzuzählen. Foren bilden sehr optimal die Frage- und Antwort-Problematik ab. Ein Wiki eignet sich hervorragend für Fließtext, wie er in Dokumentationen und Beschreibungen vorkommt. Viele Webcasts werden als Video angeboten, ohne dass die visuelle Darstellung einen Mehrwert bringt. Meist genügt eine gut verständliche und ordentlich produzierte Audiospur, um Wissen zu verteilen. Mit einer gemeinsamen und normierten Datenbasis lassen sich abgewickelte Projekte effizient miteinander vergleichen. Die daraus resultierenden Erkenntnisse bieten einen hohen Mehrwert bei der Erstellung von Prognosen für zukünftige Vorhaben.
Test & Metriken − das Maß aller Dinge
Bereits beim Überfliegen des Quality Reports 2014 erfährt man schnell, dass der neue Trend „Software testen“ ist. Unternehmen stellen vermehrt Kontingente dafür bereit, die ein ähnliches Volumen einnehmen wie die Aufwendungen für die Umsetzung des Projekts. Genau genommen löscht man an dieser Stelle Feuer mit Benzin. Bei tieferer Betrachtung wird bereits bei der Planung der Etat verdoppelt. Es liegt nicht selten im Geschick des Projektleiters, eine geeignete Deklarierung für zweckgebundene Projektmittel zu finden.
Nur deine konsequente Überprüfung der Testfall-Abdeckung durch geeignete Analyse-Werkzeuge stellt sicher, dass am Ende hinreichend getestet wurde. Auch wenn man es kaum glauben mag: In einer Zeit, in der Software-Tests so einfach wie noch nie erstellt werden können und verschiedene Paradigmen kombinierbar sind, ist eine umfangreiche und sinnvolle Testabdeckung eher die Ausnahme (siehe Abbildung 2).
Es ist hinreichend bekannt, dass sich die Fehlerfreiheit einer Software nicht beweisen lässt. Anhand der Tests weist man einzig ein definiertes Verhalten für die erstellten Szenarien nach. Automatisierte Testfälle ersetzen in keinem Fall ein manuelles Code-Review durch erfahrene Architekten. Ein einfaches Beispiel dafür sind in Java hin und wieder vorkommende verschachtelte „try catch“-Blöcke, die eine direkte Auswirkung auf den Programmfluss haben. Mitunter kann eine Verschachtelung durchaus gewollt und sinnvoll sein. In diesem Fall beschränkt sich die Fehlerbehandlung allerdings nicht einzig auf die Ausgabe des Stack-Trace in ein Logfile. Die Ursache dieses Programmierfehlers liegt in der Unerfahrenheit des Entwicklers und dem an dieser Stelle schlechten Ratschlag der IDE, für eine erwartete Fehlerbehandlung die Anweisung mit einem eigenen „try catch“-Block zu umschliessen, anstatt die vorhandene Routine durch ein zusätzliches „catch“-Statement zu ergänzen. Diesen offensichtlichen Fehler durch Testfälle erkennen zu wollen, ist aus wirtschaftlicher Betrachtung ein infantiler Ansatz.
Typische Fehlermuster lassen sich durch statische Prüfverfahren kostengünstig und effizient aufdecken. Publikationen, die sich besonders mit Codequalität und Effizienz der Programmiersprache Java beschäftigen [8, 9, 10], sind immer ein guter Ansatzpunkt, um eigene Standards zu erarbeiten.
Sehr aufschlussreich ist auch die Betrachtung von Fehlertypen. Beim Issue-Tracking und bei den Commit-Messages in SCM-Systemen der Open-Source-Projekte wie Liferay [11] oder GeoServer [12] stellt man fest, dass ein größerer Teil der Fehler das Grafische User Interface (GUI) betreffen. Dabei handelt es sich häufig um Korrekturen von Anzeigetexten in Schaltflächen und Ähnlichem. Die Meldung vornehmlicher Darstellungsfehler kann auch in der Wahrnehmung der Nutzer liegen. Für diese ist das Verhalten einer Anwendung meist eine Black Box, sodass sie entsprechend mit der Software umgehen. Es ist durchaus nicht verkehrt, bei hohen Nutzerzahlen davon auszugehen, dass die Anwendung wenig Fehler aufweist.
Das übliche Zahlenwerk der Informatik sind Software-Metriken, die dem Management ein Gefühl über die physische Größe eines Projekts geben können. Richtig angewendet, liefert eine solche Übersicht hilfreiche Argumente für Management-Entscheidungen. So lässt sich beispielsweise über die zyklische Komplexität nach McCabe [13] die Anzahl der benötigten Testfälle ableiten. Auch eine Statistik über die Lines of Code und die üblichen Zählungen der Packages, Klassen und Methoden zeigt das Wachstum eines Projekts und kann wertvolle Informationen liefern.
Eine sehr aufschlussreiche Verarbeitung dieser Informationen ist das Projekt Code-City [14], das eine solche Verteilung als Stadtplan visualisiert. Es ist eindrucksvoll Abbildung 3: Maven JDepend Plugin – Zahlen mit wenig Aussagekraft zu erkennen, an welchen Stellen gefährliche Monolithe entstehen können und wo verwaiste Klassen beziehungsweise Packages auftreten.
Abbildung 3: Maven JDepend Plugin – Zahlen mit wenig Aussagekraft
Fazit
Im Tagesgeschäft begnügt man sich damit, hektische Betriebsamkeit zu verbreiten und eine gestresste Miene aufzusetzen. Durch das Produzieren unzähliger Meter Papier wird anschließend die persönliche Produktivität belegt. Die auf diese Art und Weise verbrauchte Energie ließe sich durch konsequent überlegtes Vorgehen erheblich sinnvoller einsetzen.
Frei nach Kants „Sapere Aude“ sollten einfache Lösungen gefördert und gefordert werden. Mitarbeiter, die komplizierte Strukturen benötigen, um die eigene Genialität im Team zu unterstreichen, sind möglicherweise keine tragenden Pfeiler, auf denen sich gemeinsame Erfolge aufbauen lassen. Eine Zusammenarbeit mit unbelehrbaren Zeitgenossen ist schnell überdacht und gegebenenfalls korrigiert.
Viele Wege führen nach Rom – und Rom ist auch nicht an einem Tag erbaut worden. Es lässt sich aber nicht von der Hand weisen, dass irgendwann der Zeitpunkt gekommen ist, den ersten Spatenstich zu setzen. Auch die Auswahl der Wege ist kein unentscheidbares Problem. Es gibt sichere Wege und gefährliche Pfade, auf denen auch erfahrene Wanderer ihre liebe Not haben, sicher das Ziel zu erreichen.
Für ein erfolgreiches Projektmanagement ist es unumgänglich, den Tross auf festem und stabilem Grund zu führen. Das schließt unkonventionelle Lösungen nicht grundsätzlich aus, sofern diese angebracht sind. Die Aussage in Entscheidungsgremien: „Was Sie da vortragen, hat alles seine Richtigkeit, aber es gibt in unserem Unternehmen Prozesse, auf die sich Ihre Darstellung nicht anwenden lässt“, entkräftet man am besten mit dem Argument: „Das ist durchaus korrekt, deswegen ist es nun unsere Aufgabe, Möglichkeiten zu erarbeiten, wie wir die Unternehmensprozesse entsprechend bekannten Erfolgsstories adaptieren, anstatt unsere Zeit darauf zu verwenden, Gründe aufzuführen, damit alles beim Alten bleibt. Sie stimmen mir sicherlich zu, dass der Zweck unseres Treffens darin besteht, Probleme zu lösen, und nicht, sie zu ignorieren.“ … more voice
Das Fachwissen der eigenen Mitarbeiter ist für jede Organisation ein bedeutender Wirtschaftsfaktor. Umso wichtiger ist es, die Erfahrungen und Fachkenntnisse dauerhaft zu speichern und anderen Mitarbeitern zur Verfügung zu stellen. Ein zentraler Knowledge-Management-Server übernimmt diese Aufgabe und hilft, langfristig die Produktivität im Unternehmen zu sichern.
(c) 2011 Marco Schulz, Materna Monitor, Ausgabe 2, S.32-33
Die Komplexität der heutigen stark vernetzten Arbeitswelt erfordert ein reibungsloses Zusammenspiel unterschiedlichster Spezialisten. Eine wichtige Rolle spielt hierbei der Wissenstransfer. Erschwert wird dieser Austausch, wenn die Teammitglieder an unterschiedlichen Standorten mit verschiedenen Zeitzonen arbeiten oder aus anderen Kulturkreisen kommen. Unternehmen mit weltweiten Standorten kennen diese Problematik und haben entsprechende Strategien für ein unternehmensweites Wissens-Management entwickelt. Um dieses erfolgreich einzuführen, sollte die einzusetzende IT-Lösung als Methodik aufgefasst werden anstatt das eigentliche Werkzeug in den Vordergrund zu stellen. Haben die Verantwortlichen die Entscheidung für eine bestimmte Software-Lösung getroffen, sollte diese auch konsequent beibehalten werden. Ein häufiger Systemwechsel mindert die Qualität der Verknüpfungen zwischen den gespeicherten Inhalten. Da es keinen normierten Standard für die Repräsentation von Wissen gibt, können bei einem Wechsel auf neue Software-Lösungen erhebliche Konvertierungsverluste eintreten.
Verschiedene Mechanismen für unterschiedliche Inhalte
Informationen lassen sich in IT-Systemen auf verschiedene Weise speichern. Die einzelnen Repräsentationsformen unterscheiden sich durch die Darstellung, Strukturierung und Verwendung. Um Dokumente gemeinsam konfliktfrei bearbeiten und gleichzeitig versionieren zu können, wie es bei Spezifikationen oder Dokumentationen notwendig ist, eignen sich Wikis [1] optimal, da sie genau für diesen Einsatz ursprünglich entwickelt wurden. Die dort gespeicherten Dokumente sind üblicherweise projektspezifisch und sollten auch so organisiert werden.
Projektübergreifende Dokumente im Wiki sind zum Beispiel Fachworterklärungen, ein zentrales Abkürzungsverzeichnis oder ein Who is Who der Unternehmensmitarbeiter inklusive Kontaktdaten und Themengebieten. Letztere lassen sich wiederum mit der Fachworterklärung verknüpfen. Übergreifende Inhalte können dann zentral aktuell gehalten werden und lassen sich komfortabel in die entsprechenden Projektdokumente verlinken. Dieses Vorgehen vermeidet unnötige Wiederholungen und die zu lesenden Dokumente werden kürzer, enthalten aber dennoch alle notwendigen Informationen. Johannes Siedersleben hat bereits 2003 in seinem Buch Softwaretechnik [2] die Risiken zu langer Dokumentationen beschrieben.
Wissen, das eher den Charakter einer FAQ aufweist, sollte besser über ein Forum organisiert werden. Die Gruppierung nach Themen, in denen Fragen nach dem Muster „Wie kann ich …?“ hinterlegt sind, erleichtern das Auffinden möglicher Lösungen. Besonders attraktiv ist die Tatsache, dass ein solches Forum sich mit der Zeit dem Bedarf nach weiterentwickelt. Denn Nutzer haben die Möglichkeit, eigene Fragen zu formulieren und in das Forum einzustellen. In aller Regel lassen qualifizierte Antworten auf neu gestellte Fragen nicht lange auf sich warten.
Geeignete Kandidaten für Blogs sind zum Beispiel allgemeine Informationen zum Unternehmen, Statusberichte oder Tutorials. Dies sind Dokumente, die eher einen informativen Charakter haben, nicht formgebunden sind oder sich schwer einem speziellen Thema zuordnen lassen. Kurzinformationen (Tweets [3]) über Twitter, die in Kanälen thematisch zusammengefasst sind, können die Projektarbeit ebenfalls bereichern. Sie minimieren zusätzlich die E-Mails im eigenen Postkasten. Beispiele dafür sind Reminder zu einem bestimmten Event, ein Newsflash zu neuen Produktversionen oder eine Information über einen erfolgreich abgeschlossenen Arbeitsprozess. Tweets in die Projektarbeit zu integrieren, ist relativ neu und entsprechend rar sind hierfür geeignete Software-Lösungen.
Natürlich ist die Aufzählung von Möglichkeiten an dieser Stelle bei weitem noch nicht erschöpft. Die Beispiele vermitteln aber bereits einen guten Überblick, wie Unternehmen ihr Wissen organisieren können. Mit der Verknüpfung der einzelnen Systeme zu einem Portal [4], das eine übergreifende Suche und Benutzerverwaltung hat, entsteht so schnell ein Netzwerk, das sich auch als Cloud-Lösung eignet.
Für die Akzeptanz einer Wissensplattform ist die Anwenderfreundlichkeit ein entscheidender Faktor. Lange Einarbeitungszeiten, unübersichtliche Strukturierungen und eine umständliche Bedienung können schnell zur Ablehnung führen. Mit einer Zugangsberechtigung zu den einzelnen Inhalten auf Gruppenebene wird auch der Sicherheit genüge getan. Ein gutes Beispiel dafür ist das Enterprise Wiki Confluence [5]. Es ermöglicht, den einzelnen Dokument-Ebenen verschiedene Lese- und Schreib-Berechtigungen zuzuordnen.
Naturgemäß kann man von einem Entwickler nicht erwarten, dass er nach erfolgreicher Implementierung sein Werk mit den richtigen Worten für die Nachwelt verständlich beschreibt. Dass die Qualität der Texte in vielen Dokumentationen nicht immer ausreichend ist, hat auch die Hochschule Merseburg erkannt und bietet den Studiengang Technische Redaktion [6] an. Als geeignetes Mittel zur Qualitätssicherung der Inhalte hat sich daher das Querlesen durch andere Projektmitglieder erwiesen. Um das Verfassen von Texten zu erleichtern, ist es hilfreich, einen kleinen Leitfaden – ähnlich der Coding Convention – bereitzustellen.
Fazit
Eine Wissensdatenbank lässt sich nicht von heute auf morgen umsetzen. Es braucht Zeit, bis darin genügend Informationen zusammengetragen sind. Erst durch Interaktion und Korrekturen von Unverständlichkeiten erreicht das Wissen eine Qualität, die zum Transfer einlädt. Jeder Mitarbeiter sollte dazu ermutigt werden, vorhandene Texte mit neuen Erkenntnissen anzureichern, unverständliche Passagen aufzulösen oder Suchbegriffe zu ergänzen. Wenn der Prozess der Wissensschöpfung und Verteilung in dieser Form gelebt wird, werden weniger Dokumente verwaisen und die Informationen sind stets aktuell.
Die Software-Entwicklung bietet einige äußerst effiziente Möglichkeiten, wiederkehrende Handgriffe durch Automatisierung zu vereinfachen. Das Wegfallen lästiger, sich wiederholender, monotoner Aufgaben und eine dadurch reduzierte Fehlerhäufigkeit im Entwicklungsprozess sind längst nicht alle Facetten dieser Thematik.
(c) 2011 Marco Schulz, Materna Monitor, Ausgabe 1, S.32-34
Die Motivation, Automatismen in der IT-Landschaft zu etablieren, ist weitgehend die Gleiche. Wiederkehrende Aufgaben sollen vereinfacht und ohne menschliches Zutun maschinell gelöst werden. Die Vorteile sind weniger Fehler bei der Benutzung von IT-Systemen, was wiederum die Kosten senkt. So einfach und vorteilhaft sich der Gedanke der selbstständig ablaufenden Prozesse auch anhört, die Umsetzung ist weniger trivial. Schnell wird klar, dass für jede identifizierte Möglichkeit einer Automation nicht immer eine Umsetzung machbar ist. Auch hier gilt der Grundsatz: Je komplexer ein Problem ist, umso aufwendiger ist dessen Lösung.
Um abzuwägen, ob sich der wirtschaftliche Aufwand zur Einführung bestimmter Automatismen lohnt, müssen die Kosten einer manuellen Lösung mit dem Faktor der zu wiederholenden Häufigkeit dieser Arbeit multipliziert werden. Diesen Kosten sind die Aufwendungen für die Entwicklung und den Betrieb der automatisierten Lösung entgegenzusetzen. Anhand dieser Gegenüberstellung wird schnell klar, ob ein Unternehmen die angedachte Verbesserung durchführen sollte.
Tools unterstützen den Entwicklungsprozess
Besonders bei der Entwicklung von Software-Projekten gibt es einen erhebliches Optimierungspotenzial durch automatische Prozesse. Dabei unterstützen die Entwickler eine Vielzahl an Tools, die es gekonnt zu orchestrieren gilt. Besonders das Konfigurations- und Release-Management beschäftigt sich sehr ausführlich mit dem praktischen Einsatz verschiedenster Werkzeuge zur Automatisierung des Software-Entwicklungsprozesses.
Das Vorhandensein einer separaten Build-Logik, beispielsweise in Form eines simplen Shell-Skriptes, ist zwar bereits ein guter Ansatz, aber nicht immer zielführend. Für solche Fälle sind plattformunabhängige Lösungen notwendig, da die Entwicklung mit sehr hoher Wahrscheinlichkeit in einem heterogenen Umfeld stattfindet. Eine Insellösung bedeutet stets erhöhten Anpassungs- und Pflegeaufwand. Schließlich sollen die Automatisierungsbestrebungen vorhandene Abläufe vereinfachen. Aktuelle Build-Werkzeuge wie Maven und Ant nutzen diesen Vorteil der Plattformunabhängigkeit. Die Kapselung der gesamten Build-Logik erfolgt bei beiden Werkzeugen in separaten XML-Dateien. Da sich XML bereits als Standard in der Software-Entwicklung etabliert hat, ist die Lernkurve steiler als bei rudimentären Lösungen.
Die Nutzung zentraler Build-Logiken bildet die Grundlage für weitere Automatismen während der Entwicklungsarbeit. Einen Aspekt bilden dabei automatisierte Tests in Form von UnitTests in einer Continuous-Integration-(CI)-Umgebung. Eine CI-Lösung fügt alle Teile einer Software zu einem Ganzen zusammen und arbeitet alle definierten Testfälle ab. Konnte die Software nicht gebaut werden oder ist ein Test fehlgeschlagen, wird der Entwickler per E-Mail benachrichtigt, um den Fehler schnell zu beheben. Moderne CI-Server werden gegen ein Versionsverwaltungssystem, wie beispielsweise Subversion oder Git, konfiguriert. Das bewirkt, dass der Server ein Build erst dann beginnt, wenn auch tatsächlich Änderungen im Sourcecode gemacht wurden.
Komplexe Software-Systeme verwenden in aller Regel Abhängigkeiten zu fremden Komponenten (Bibliotheken), die nicht durch das eigene Projekt beeinflusst werden können. Die effiziente Verwaltung der im Projekt verwendeten Artefakte ist die Hauptstärke des Build-Tools Maven, was zu dessen starker Verbreitung beigetragen hat. Bei richtiger Verwendung ist es so nicht mehr nötig, binäre Programmteile innerhalb der Versionsverwaltung zu archivieren, was zu kleineren Repositories und kürzeren Commit-Zeiten (erfolgreicher Abschluss einer Transaktion) führt. Neue Versionen der verwendeten Bibliotheken können schneller eingebunden und ausprobiert werden, ohne dass sie fehleranfällige manuelle Kopieraktionen verursachen. Inhouse entwickelte Bibliotheken lassen sich im Sinne der Wiederverwendung mit der Verwendung eines eigenen Repository-Servers (Apache Nexus) im Firmennetzwerk auf einfache Weise geschützt verteilen.
Bei der Evaluierung eines Build-Werkzeuges sollte die Möglichkeit des Reportings nicht vernachlässigt werden. Die automatisierte Überwachung der Code-Qualität anhand von Metriken, beispielsweise durch das Tool Checkstyle, ist ein hervorragendes Instrument für die Projektleitung, um den aktuellen Stand des Projekts realistisch zu beurteilen.
Nicht zu viele neue Technologien
Bei allen Möglichkeiten, Prozesse zu automatisieren, können mehrere Wege beschritten werden. Nicht selten führen Entwicklerteams lange Diskussionen darüber, welches Werkzeug besonders für das aktuelle Projekt geeignet ist. Diese Frage lässt sich schwer allgemein beantworten, da jedes Projekt einzigartig ist und die Vor- und Nachteile verschiedener Werkzeuge mit den Projektanforderungen abgeglichen werden müssen.
Im praktischen Einsatz hat sich die Beschränkung auf maximal zwei neuartige Technologien im Projekt bewährt. Ob ein Werkzeug geeignet ist, entschiedet auch die Tatsache, ob im Unternehmen Personen mit dem geeigneten Know-how verfügbar sind. Eine gute Lösung ist eine vom Management freigegebene Liste mit Empfehlungen der eingesetzten Tools, die bereits verwendet werden oder sich in die bestehende Systemlandschaft integrieren lassen. Damit wird sichergestellt, dass die eingesetzten Werkzeuge übersichtlich und beherrschbar bleiben.
Projekte, die über viele Jahre laufen, müssen sich in größeren Abständen einer Modernisierung der verwendeten Technologien unterziehen. In diesem Zusammenhang müssen geeignete Zeitpunkte gefunden werden, um mit möglichst wenig Aufwand zur neuen Technologie zu migrieren. Sinnvolle Termine, um auf eine neuere Technologie zu schwenken, sind beispielsweise ein Wechsel auf ein neues Major Release des eigenen Projektes. Dieses Vorgehen erlaubt eine saubere Trennung, ohne alte Projektstände auf die neue Technik migrieren zu müssen. In vielen Fällen ist das auch nicht so einfach möglich.
Fazit
Die Verwendung von Automatismen zur Software-Entwicklung kann bei bedachtem Einsatz das Erreichen des Projektziels tatkräftig unterstützen. Wie bei allen Dingen ist der übermäßige Einsatz mit einigen Risiken verbunden. Die verwendete Infrastruktur muss bei aller Technisierung verständlich und beherrschbar bleiben, so dass bei Systemausfällen die Projektarbeit nicht ins Stocken gerät.