14.05.2018
Software-Code
1. Teil: „Gezielte Evolution statt wahlloser Wucherung“
Gezielte Evolution statt wahlloser Wucherung
Autor: Hendrik Lösch
mmatee / Shutterstock.com
Es gibt viele Gründe, Programmen frischen Code einzubauen. Innerhalb von Software ist Evolution wichtig, um natürlich gewachsene Verflechtungen durch eine geplante Architektur zu ersetzen.
Entwickler sind meist stark auf den Code ihrer Anwendung fokussiert. Diesen verstehen sie als ein Ergebnis aus den umzusetzenden Anforderungen und konzentriertem Nachdenken. Tatsächlich unterliegen die Strukturen, die Entwickler schaffen, noch einer Vielzahl anderer Einflüsse, die ihnen unter Umständen aber nicht bewusst sind.
Museumsreif
Dieser Alterungsprozess von Software ist aber nicht nur auf schlechte Programmierung zurückzuführen. Software altert auch durch den technischen Fortschritt. Darüber hinaus führen auch Veränderungen in der Gesetzgebung oder in Unternehmensprozessen dazu, dass ein Software-System nicht mehr aktuell ist. Wenn sich das System nicht mehr an Veränderungen anpassen lässt, wird es irgendwann abgeschaltet.
Diese letzte Phase wird als „Close Down“ bezeichnet. Dieser Close Down muss mit dem Kunden abgesprochen sein und den vertraglichen Rahmenbedingungen entsprechen.
Vor dem Close Down und nach der Maintenance-Phase gibt es zudem noch das „Phase Out“. In dieser Zeit ist das Ende des Systems schon offensichtlich, da nicht mehr aktiv in seine Werterhaltung investiert wird. Eigentlich wird es hier nur noch seinen letzten verbliebenen Nutzern zur Verfügung gestellt, bis sein Betrieb unwirtschaftlich wird.
2. Teil: „Software-Evolution“
Software-Evolution
Software-Evolution“. Zwar haben sich die Begriffe des Developments und der Maintenance bereits in den Siebzigerjahren etabliert, jedoch täuschen sie darüber hinweg, dass sich damals herausstellte, dass sie nicht ausreichen, um die Besonderheiten zu beschreiben, die sich daraus ergeben, wenn Software bereits genutzt wird, obwohl ihre Entwicklung noch nicht abgeschlossen ist.
Es gibt noch eine weitere Phase zwischen Development und Maintenance: die „Selbst wenn also beispielsweise eine Lohnabrechnungs-Software über alle Merkmale wie automatisiertes Umsetzen von Arbeitsprozessen, Datenexporte, Validierungen und Datenspeicherung verfügt, so muss sie angepasst werden, sobald gesetzliche Regelungen geändert werden. Geschieht das nicht, arbeitet sie falsch. Wenn dies also nicht als Wartung bezeichnet werden kann, ist es dann mit der reinen Entwicklung gleichzusetzen? Im Alltag wäre diese Frage höchstwahrscheinlich mit Ja zu beantworten, weil wir tatsächlich meist unbewusst die Phasen der reinen Entwicklung und die der Evolution miteinander vermischen.
Entwicklung vs. Evolution
Tatsächlich sind Entwickler im Development-Prozess so lange sicher, wie ihr Produkt noch nicht außerhalb des Teams verwendet wird. Unter diesen Laborbedingungen muss weder auf Breaking Changes geachtet werden noch sind Hotfixes zu erstellen, um kritische Laufzeitfehler zu beseitigen. Das Team kann seinem Zeitplan folgen und ist fast frei von unangenehmen externen Einflüssen. In dem Moment, in dem das System jedoch veröffentlicht wird, muss es sich in der realen Welt behaupten. Dann ist plötzlich darauf zu achten, wie die Software bisher verwendet wurde. Sie wird mit tatsächlichen Arbeitsabläufen konfrontiert, und dies kann nicht nur zu Fehlern, sondern auch zu Änderungen bei den Anforderungen, also Change Requests, führen. Wie wichtig dabei die Priorisierung und Definition von Fehlern, Anforderungsänderungen und Merkmalen ist, zeigt sich in den Gerichtsprozessen, die sich nur um die Frage drehen, welche Schadenssummen sich ergeben, weil ein Zulieferer vermeintlich nicht adäquat auf ein gemeldetes Fehlverhalten reagiert hat.
Software entwickelt sich nach dem ersten Release evolutionär entlang den tatsächlichen Gegebenheiten. Über die Jahre hinweg nimmt der Anteil der Umsetzung von Merkmalen und Funktionen immer weniger Raum ein. Damit sinkt die wertsteigernde Arbeit und wird durch werterhaltende Tätigkeiten wie Stabilisierung, Optimierung und sogar Sanierungen ersetzt. Je nachdem wie geordnet der Entwicklungsprozess auch nach einem Release noch verläuft, ergibt sich daraus, wie stabil die internen Strukturen der Software sind und wie schnell sich diese an neue Gegebenheiten anpassen kann. Darüber hinaus steigen aber auch die fixen Betriebskosten im Vergleich zu den laufenden Entwicklungskosten. Die Unterscheidung zwischen der Entwicklungs- und der Evolutionsphase ist daher gerade aus Sicht der Kosten sehr wichtig. Während die Entwicklung am Anfang gern als einmaliger Kostenblock angesehen wird, sind die Kosten des Betriebs schlecht einzuschätzen. Das Bereitstellen von Servern, ein Support, der Kundenanfragen bearbeitet, das Vorhalten von Entwicklerkapazitäten, um kritische Fehler zu beseitigen, und Ähnliches können sich auf Dauer zu einem weitaus größeren Posten entwickeln, als es die ursprüngliche Entwicklung war.
An dieser Stelle lassen sich dann auch nur schwer Einsparungen gegenüber der Entwicklung erzielen. Während sich ein Entwicklungsprojekt im schlimmsten Fall stoppen lässt und sich die Kosten somit schlagartig verringern, bedeutet der Stopp während der Evolutionsphase einen Close Down mit all seinen Folgen. Das heißt: Mit dem Übergang von der Entwicklungsphase hin zur Evolution geht der Betreiber Verpflichtungen ein, denen er zumindest zeitweise noch folgen muss, selbst wenn es sich finanziell eigentlich schon nicht mehr rechnet.
Evolution vs. agil
Wenn die Phase der Software-Evolution so bedeutend ist und ihre Definition nun schon über vierzig Jahre zurückliegt, wie kommt es, dass sie so unbekannt ist? Einer der Hauptgründe dafür liegt wahrscheinlich in einer besonderen Ausprägung der Theorien hinter der Software-Evolution: der agilen Software-Entwicklung. Scrum, Kanban und andere Methodiken bewirken, dass sich Entwickler den besonderen Gegebenheiten nach einem Software-Release aktiv stellen, indem man sie durch die direkte Beteiligung der Fachbereiche möglichst früh herausfordert.
Gerade das iterativ inkrementelle Vorgehen von Scrum-Teams spiegelt einen zentralen Gedanken der Software-Evolution wider. Die Idee dahinter ist, dass am Ende jeder Iteration ein Inkrement der Software steht, das theoretisch auch produktiv eingesetzt werden könnte. Während der Iterationen durchläuft die Software eine Form der Evolution, die kontinuierlich überwacht wird. Mutiert sie bei diesem Prozess in eine ungewollte Richtung, kann dieser Mutation entgegengewirkt werden, bevor sie sich schädlich auswirkt.
3. Teil: „Wenn Scrum nicht funktioniert“
Wenn Scrum nicht funktioniert
Eigentlich sollten während eines Sprints keine Änderungen an den Aufgaben vorgenommen werden. Kommen plötzlich weitere Arbeitspakete hinzu, dann stört dies den Ablauf von Regelterminen (wie Review, Planning oder Retro), führt zu nicht abzuschätzenden Mehraufwänden und macht damit die ursprünglichen Einschätzungen zunichte.
Wenn jedoch die Schätzungen des Teams zu oft und zu weit von den tatsächlichen Werten abweichen, zerstört dies wiederum das Vertrauen in das gesamte Vorgehen, wodurch agile Arbeitsweisen schnell einmal komplett in Frage stehen können.
Besser früh auf Kanban wechseln
Typische Kritikpunkte am agilen Vorgehen wie „endlose Entwicklungszeiten“, „unerwartet hohe Aufwände“ und „unkoordinierte Aufgabenbewältigung“ ergeben sich somit nicht zuletzt auch, weil die eigentliche Evolution von Software falsch verstanden und ungünstig auf sie reagiert wurde. So lässt sich den beschriebenen Schwierigkeiten beispielsweise durch eine Verkürzung der Sprint-Zeiten auf zum Beispiel eine Woche entgegenwirken oder indem gleich von Scrum auf Kanban umgesattelt wird.
Zuvor aber wäre zunächst zu prüfen, warum so oft auf Meldungen aus der Produktion reagiert wird, und ob dies überhaupt in einer Geschwindigkeit passieren muss, die den gesamten Entwicklungsprozess aus den Angeln hebt. Häufig kann hier schon geschickte Planung und Priorisierung auf Kundenanfragen helfen. Dazu ist jedoch klar einzuschätzen, welche Dinge tatsächlich wie zu handhaben sind. Das betrifft einen der Kernpunkte der Wissenschaft hinter der Software-Evolution.
4. Teil: „Gezielte Software-Evolution“
Gezielte Software-Evolution
Dies zeigt sich beispielsweise auch in einem grundsätzlichen Missverständnis in Bezug auf Refaktorisierungen. Der Entwickler und Autor Martin Fowler schrieb schon 2004, dass seine ursprüngliche Absicht hinter dem Begriff „Refactoring“ eigentlich in lokal begrenzten Strukturanpassungen lag, die sich nicht auf das Verhalten der Software auswirken. Demnach sollte eine Refaktorisierung die Software nicht länger als zwei Minuten unbrauchbar machen.
Im Alltag wird Code aber immer wieder auch in größerem Maß umstrukturiert, und dabei werden ganze Entwicklungsteams über Tage hinweg behindert. Im Englischen würde man von einem Restructuring sprechen.
Rütteln an den Grundfesten
Umstrukturierungen sind innerhalb von Software-Systemen nach einigen Monaten oder Jahren notwendig, um die natürlich gewachsenen Verflechtungen aufzubrechen und durch eine geplante Architektur zu ersetzen. Dazu muss die Architektur aber vor der Umstrukturierung auch wirklich geplant worden sein und darf sich nicht während des Vorgangs per Zufall ergeben. Ist sie jedoch ein Ergebnis des Zufalls, wird sie sich auf Dauer ebenfalls als ungünstig herausstellen. Das Missverständnis zwischen Refaktorisierung und Restrukturierung ist somit, dass Entwickler immer wieder meinen, sie würden nur eine kleine Änderung am Code vornehmen; tatsächlich rütteln sie dabei aber oft an den Grundfesten der Applikation, da sie sich nicht ausgiebig mit den tatsächlichen Zusammenhängen beschäftigt haben. Die Krux an dieser Situation ist, dass die Evolution von Software solcherlei Umstrukturierungen auf jeden Fall notwendig macht. Unkontrollierter Aktionismus jedoch ist nicht hilfreich.
Es muss sich rechnen
Die Wissenschaft der Software-Evolution bietet hier Mittel und Wege zur Bewertung. Dazu gehören neben den viel beachteten Code- und Strukturmetriken auch Verfahren zum Umgestalten der Architektur und Möglichkeiten der Kosten-Nutzen-Analyse.
Letzteres mag verwundern, ist aber wichtig, da auch die Software-Entwicklung zum ökonomischen Handeln verpflichtet ist. Nur weil ich Code verändern kann und er mir in seinem jetzigen Zustand nicht gefällt, bedeutet dies noch lange nicht, dass es auch wirtschaftlich sinnvoll ist, ihn zu verändern. Aus diesem Grund hat sich das Ideal etabliert, dass Refaktorisierungen nie einzeln durchgeführt werden sollten. Vielmehr sollten sie immer in Kombination mit einem umzusetzenden Merkmal oder mit dem Beheben von Programmierfehlern verbunden werden. Auf diese Weise werden die strukturellen Anpassungen dann zu einem Teil der eigentlichen Aufgabe (das neue Merkmal) und können besser eingearbeitet werden.
Das macht den Gesamtaufwand ökonomischer und relativiert ihn schon durch die Umsetzung der Aufgabe. Umstrukturierungen in größerem Maß mit dem Ziel, technische Schulden großflächig abzubauen, folgen im Grunde dem gleichen Muster. Sie können entweder erfolgen, wenn die Umsetzung neuer Merkmale ohne sie nur zu noch größeren technischen Schulden führen würde oder wenn sie der Sanierung bestimmter Teilbereiche der Software vorangestellt werden können, was beispielsweise dann passiert, wenn das User Interface auf eine andere Technologie gehoben werden soll.
Quellen
- Wikipedia, Gesetz von Conway
- Tom Mens, Serge Demeyer, Software Evolution, ISBN 978-3-540-76440-3
- Harry M. Sneed und Richard Seidl, Softwareevolution
- Tom Gilb, Evolutionary Delivery vs Waterfall Model, ACM Software Engineering Notes, Juli 1985
- Martin Fowler, RefactoringMalapropism
- Donald Knuth
Huawei Roadshow 2024
Technologie auf Rädern - der Show-Truck von Huawei ist unterwegs
Die Huawei Europe Enterprise Roadshow läuft dieses Jahr unter dem Thema "Digital & Green: Accelerate Industrial Intelligence". Im Show-Truck zeigt das Unternehmen neueste Produkte und Lösungen. Ziel ist es, Kunden und Partner zusammenzubringen.
>>
Tools
GitLab Duo Chat mit KI-Chat-Unterstützung
Der DevSecOps-Plattform-Anbieter GitLab führt den GitLab Duo Chat ein. Dieses Tool integriert Künstliche Intelligenz in die DevSecOps-Workflows.
>>
Forschung
KI macht Gebärdensprache zugänglicher
Ein KI-Tool der Universität Leiden für "Wörterbücher" erkennt Positionen und Bewegungen der Hände bei der Darstellung unterschiedlicher Gebärdensprachen.
>>
Cyberbedrohungen überall
IT-Sicherheit unter der Lupe
Cybersecurity ist essentiell in der IT-Planung, doch Prioritätenkonflikte und die Vielfalt der Aufgaben limitieren oft die Umsetzung. Das größte Sicherheitsrisiko bleibt der Mensch.
>>