[SL] Wohin wollen wir verbessern?

Was heißt eigentlich “besser”? Mit anderen Worten, woher wissen wir, dass es beim Kaizen in die richtige Richtung geht? Im klassischen Lean Management in der Fertigung ist eine Richtung vorgegeben: der Zeitraum von der Bestellung bis zum Zahlungseingang soll immer weiter verkürzt werden.

Alles, was wir tun, ist, auf die Durchlaufzeit zu achten, und zwar von dem Moment an, in dem wir einen Kundenauftrag erhalten, bis zu dem Moment, da wir das Geld in Empfang nehmen. Wir verkürzen die Durchlaufzeit, indem wir alle Bestandteile eliminieren, die keinen Mehrwert generieren.” (Taiichi Ohno, zitiert nach Jeffrey K. Liker: Der Toyota Weg)

Eine Methode wie Kanban steht dann einfach im Dienste des übergeordneten Ziels – indem die Bestände begrenzt werden, wird auch die Durchlaufzeit begrenzt.

Wir können das Prinzip “Möglichst schnell von der Bestellung bis zum Zahlungseingang” auf das IT-Projektgeschäft bzw. auf die softwarelastige Produktentwicklung übertragen. Hier gilt es, die Zeit von der Idee bis zur Umsetzung immer weiter zu verringern. (Die Poppendiecks haben dafür den schönen Ausdruck “From Concept to Cash”) Daraus kann man weitere Ziele ableiten, wie etwa Steigerung der Qualität (zur Vermeidung von Nacharbeit) oder häufigere Releases (für schnelleres Feedback und geringere Verzögerungskosten).

Bei Two Second Lean heißt es einfach “Fix what bugs you!”; man hat also die Erlaubnis, alles, was irgendwie hinderlich ist und zu Reibungsverlusten führt, zu verbessern. Dieser Hinweis passt gut für die eher “qualitativen” Verbesserungen, etwa

Ich will aber mehr über die Dinge reden, bei denen sich eine Verbesserung auch quantitativ fassen lässt. Auch in der Fabrik geht man ja hin und misst Arbeitsabläufe mit der Stoppuhr, zählt Bestände usw., damit man die Situation analysieren und einen Vorher-Nachher-Vergleich machen kann.

Wir beginnen mit einem übergreifenden Ziel, das den vorläufigen Endpunkt der Reise beschreibt. Das sollte möglichst konkret, ambitioniert und messbar sein; etwa: “Wir wollen von quartalsweisen Releases auf ein Release pro Woche kommen.” oder: “Derzeit machen wir durchschnittlich 25 Hotfixes auf der Produktivinstanz pro Monat, das soll auf Null gesenkt werden.” Die vielen kleinen Schritte, die man beim Kaizen macht, sollten natürlich auch eine messbare Verbesserung in Richtung auf das übergreifende Ziel bringen. An ein paar Beispielen will ich nun zeigen, wie man so etwas sinnvoll objektivieren kann.

Häufigere Releases sind eng verbunden mit dem Overhead für ein Release (Dinge wie manuelle Tests, Bereitstellung von Testumgebungen usw.) Wenn wir den Overhead für ein Release von beispielsweise derzeit 14 Tagen auf 2 Stunden senken, können Releases wesentlich häufiger gemacht werden. Es empfiehlt sich dann zu messen (oder aus dem Gedächtnis zu rekonstruieren), wie groß der Overhead derzeit ist, und wie sich die Zeit auf einzelen Themen verteilt. Im Rahmen eines oder mehrerer Investitionsreleases werden dann die größten Brocken zuerst angegangen. Die technischen Mittel und die Erfolgskontrolle kann man am Beginn gemeinsam entwickeln, etwa: Wir machen Umgebungsbereitstellung (Infrastructure as Code) mit Ansible und führen ein Burndown-Chart, das zeigt, wie sich der Release-Overhead mit der Zeit verringert.

Abdeckung des Codes durch automatisierte Tests kann man natürlich direkt in Prozent der von Tests erreichten Codezeilen messen. Das ist brauchbar, wenn auch nicht immer zuverlässig – man kann leider viel zu einfach die Testabdeckung steigern, ohne wirklich etwas zu testen. Es ist manchmal nützlich, einen Mechanismus einzuführen, der eine Code-Änderung ablehnt, wenn sie die Testabdeckung verringert, oder wenn sie ungetesteten Code betrifft.

Objektiver ist die indirekte Messung: automatisierte Tests sollen verhindern, dass Probleme erst im Produktivbetrieb sichtbar werden. Daher kann man ihre Wirksamkeit am besten daran sehen, dass solche Probleme seltener werden. Dieser Indikator ist zwar realistischer, hat aber auch eine längere Vorlaufzeit.

Refactoring dient zur Verbesserung der internen Qualität des Codes. Hinsichtlich der Ziele muss man unterscheiden zwischen strategischem und taktischem Refactoring. Strategisch ist zum Beispiel das Aufspalten eines Monolithen in Microservices, oder das Abbauen von technischen Schulden, etwa das Entfernen von obsolet gewordenen Komplikationen in der Architektur. Das sind Änderungen, die in längeren Zeiträumen gemacht werden. Hier lohnt es sich, einen expliziten Plan zu machen, der nicht nur die Zielarchitektur beschreibt, sondern auch einen Weg, wie man sie in kleinen risikoarmen Schritten erreichen kann. Daraus wird sich oft eine Metrik für den Fortschritt ableiten lassen.

Ein Beispiel: Wenn die Geschäftslogik in SQL in 239 stored procedures und etlichen Triggern abgelegt ist, kann ein Ziel des Refactorings sein, diese Geschäftslogik auszulagern und in einem Service zu kapseln. Der Service kann danach von mehreren Applikationen genutzt werden, wir vermeiden so das Problem der engen Kopplung verschiedener Applikationen über eine gemeinsame Datenbank (Integration Database). Eine geeignete Metrik für den Fortschritt wäre dann z.B. die Anzahl der noch verbleibenden Stored Procedures über die Zeit.

Das “taktische” Refactoring bezieht sich auf kleine Bereiche im Code, jedes einzelne “Manöver” sollte im Rahmen eines Tickets abzuschließen sein. Das TDD (test driven development) geht von sich aus schon in kleinen Schritten vor: Die Entwicklung durchläuft viele “red green refactor”-Zyklen. Schreibe einen Test, der fehlschlägt (red), implementiere die kleinstmögliche Änderung, die den Test erfüllt (green) und dann strukturiere den Code so, dass er gut den aktuellen Anforderungen entspricht (refactor).

Die “richtige Richtung” ist also gegeben durch die aktuell zu erfüllenden Anforderungen und einen Sinn für gute Struktur des Codes. Darüber hinaus gibt es ein paar objektive Metriken, die sich automatisch prüfen lassen. Im Ruby-Ökosystem gibt es z.B. das Tool Rubocop, wo auch Metriken für Code-Komplexität integriert werden. Services wie etwa CodeClimate Quality sind für verschiedene Programmiersprachen verfügbar.

Sie sehen hoffentlich an diesen Beispielen, dass es oft brauchbare Maßstäbe gibt, an denen man ablesen kann, wie gut man auf dem Weg der kontinuierlichen Verbesserung vorankommt.

Matthias Berth

Alle Emails