Stiller Killer #1: Technische Schulden

Im Soft­wa­reen­twick­lung­sprozess kön­nen Zustände entste­hen, die den Pro­jek­ter­folg verzögern, gefährden oder gän­zlich unmöglich machen. Schon manch­es Pro­jekt musste wegen man­gel­nden Bewusst­seins über solche Risiken wieder­holt neu aufge­set­zt oder gän­zlich begraben wer­den. Selb­st dann jedoch bleiben die Ursachen häu­fig im Ver­bor­ge­nen. Ich nenne sie daher stille Killer – die unerkan­nte, zuweilen auch nur unter­schätzte Gefahr.

Der Begriff der Tech­nis­chen Schulden ist heute den meis­ten, die in irgen­dein­er Weise mit Soft­wa­reen­twick­lung zu tun haben, geläu­fig. In agilen Entwick­lerteams wird er für gewöhn­lich regelmäßig the­ma­tisiert. Unter dem Kürzel TD für Englisch Tech­ni­cal Debt wird die Tech­nis­che Schuld gerne bemüht, um Verzögerun­gen oder Fehler­rat­en zu begrün­den. Und obwohl das Konzept der Tech­nis­chen Schuld in den let­zten Jahren auf unrühm­liche Weise pop­ulär gewor­den ist, gibt es einen Umstand, der allzu leicht überse­hen wird: die Entste­hung von Tech­nis­ch­er Schuld ist unvermeidbar.

Technische Schuld ist ein Naturgesetz

Wir sind nicht hellsichtig, und Zeit ist ein knappes Gut (glauben wir)

Soviel wir uns auch bemühen, wir kön­nen nicht jedes Detail vorausah­nen. Auch kön­nen wir uns nicht beliebig viel Zeit nehmen, immer die ide­ale Lösung zu entwer­fen. So manche weitre­ichende Entschei­dung tre­f­fen wir inner­halb von Sekun­den. Manch­mal bemerken wir zu spät, dass uns zur opti­malen Umset­zung schlicht Wis­sen fehlte.

Architektur erodiert

Und dann ist da noch etwas, das Dr. Car­o­la Lilien­thal als Architek­turero­sion beze­ich­net. Damit ist gemeint, dass selb­st ein ide­al­er Entwurf mit der Zeit seine Gültigkeit ver­lieren kann, und aus ein­er ehe­mals guten mit der Zeit eine weniger gute Imple­men­tierung wird. Eine Architek­tur, die gestern noch per­fekt war, ist heute falsch, da die Umstände sich verän­dert haben. Geset­zliche Vor­gaben oder neue Ver­fahren im Zahlungsverkehr sind gute Beispiele dafür. Davon abge­se­hen entste­ht Ero­sion häu­fig auch dadurch, dass ver­schiedene Entwick­ler mit unter­schiedlichem Hin­ter­grund und Sachver­stand den Code mit der Zeit in ein Sta­di­um zunehmender Unord­nung über­führen. Kurz gesagt: der Code wird mit der Zeit immer schlechter. In vie­len Soft­ware­pro­jek­ten ist das eine fest­ste­hende Tatsache.

frei nach C. Lilien­thal: der „Kor­ri­dor geringer Tech­nis­ch­er Schuld“

Es ist also schw­er, TDs in Soft­waresys­te­men ganz zu ver­mei­den. Wohl aber gibt es Möglichkeit­en, die Schä­den zu min­imieren, indem wir ihr Aus­maß inner­halb eines „Kor­ri­dors geringer tech­nis­ch­er Schulden“ (Lilien­thal) hal­ten. Doch zunächst wollen wir ver­suchen zu umreißen, was Tech­nis­che Schuld für uns bedeutet.

Definition

Tat­säch­lich gibt es zur Def­i­n­i­tion von TD unter­schiedliche Betra­ch­tungsweisen. Die ein­fach­ste ist, jed­wede unsachgemäße Pro­gram­mierung als TD zu beze­ich­nen. Unsachgemäß bedeutet hier: den Stand der Kun­st mis­sach­t­end oder schlichtweg schäbig programmiert. 

Eine andere Auf­fas­sung besagt, dass es immer eine bewusste Entschei­dung sein muss, Tech­nis­che Schulden aufzunehmen – schlechte Pro­gram­mierung oder man­gel­hafte Architek­tur fie­len dann also nicht darunter. Hier wür­den wir kurzfristig und bewusst ein TD akzep­tieren, um ein anderes Ziel, beispiel­sweise einen bevorste­hen­den Releaseter­min, schneller zu erreichen. 

Als Ver­all­ge­meinerung bei­der Sicht­en ließe sich definieren, dass Tech­nis­che Schuld poten­ziell jed­er Zus­tand ein­er Soft­ware ist, der eine naht­lose Weit­er­en­twick­lung ver­hin­dert.

Gründe und Auswirkungen

Aufgeschobene Refactorings

Sobald durch eine anste­hende Erweiterung die Umstruk­turierung beste­hen­der Teile der Soft­ware erforder­lich wird, dro­ht ein Schulden­loch. Ob es sich auf­tut und wir hine­in­fall­en hängt davon ab, ob das Refac­tor­ing durchge­führt wird oder nicht. Wenn ja, ist alles gut – keine TD aufge­baut. Wenn wir es nicht tun, haben wir von dem Moment an eine TD, die mit jedem kom­menden Change Request ihre Zin­sen ein­fordern wird. Der Zins­eszin­sef­fekt ist bekan­ntlich ein expo­nen­tielles Phänomen. Das gilt auch in der Softwareentwicklung.

Häu­fig wird mit der Umset­zung von Erweiterun­gen begonnen, ohne vorher zu prüfen, ob die beste­hende Architek­tur den neuen Anforderun­gen stand­hält. Nötige Refac­tor­ings wer­den so erst spät erkan­nt, wenn über­haupt. Nach zwei oder drei Erweiterungszyklen ist das Dilem­ma oft­mals bere­its so weit fort­geschrit­ten, dass Maß­nah­men zur Behe­bung sehr deut­lich zu Buche schla­gen wür­den. Die Lösung heißt dann allzu oft „Augen zu und durch“ – und so manövri­ert sich das Pro­jekt selb­st immer tiefer in den Schulden­berg hinein. In dieser Phase begin­nen die Schmerzen groß genug zu wer­den, um Aufmerk­samkeit „von oben“, also des Man­age­ments oder des Kun­den zu gewin­nen. Die Frage lautet dann, warum selb­st kleine Fea­ture-Erweiterun­gen „so lange“ dauern. 

Featuritis

Es ist eine Bin­sen­weisheit, dass viele Soft­ware­pro­jek­te mit Bazil­lus Fea­tu­ri­tis infiziert sind. Das giftige Stof­fwech­sel­pro­dukt dieses Erregers ist TD. Eine der Schwierigkeit­en bei der Diag­nose von TD ist die lange Inku­ba­tion­szeit. Während funk­tionale Soft­warefehler meist frühzeit­ig zutage treten, wirken sich TDs eine Zeit lang eher unter­schwellig aus. Wenn ihre unschö­nen Symp­tome wie erschw­erte Wart­barkeit und steigende Defect-Rat­en sich endlich zeigen, ist das Soft­ware­pro­dukt bere­its der­art herun­tergewirtschaftet, dass ein Gegen­s­teuern nicht mehr ohne deut­lichen Mehraufwand zu bew­erk­stel­li­gen ist. Das liegt daran, dass TD ein Aspekt der inneren Soft­ware­qual­ität ist, beziehungsweise ein Man­gel der­sel­ben. Die innere Qual­ität eines Pro­duk­ts ist von außen nicht direkt sicht­bar. Sie wird nur dann wahrgenom­men, wenn sie so dürftig ist, dass sie zu Fehlfunk­tio­nen oder steigen­den Aufwän­den führt.

Das Gesetz von Conway

Nach dem vielz­i­tierten Gesetz von Con­way, englisch Conway‘s Law, entsprechen die Struk­turen eines Soft­waresys­tems zwangsläu­fig denen der Organ­i­sa­tion, die es her­vorge­bracht hat. Ver­schiedene Stu­di­en haben dieses Pos­tu­lat aus den Achtziger­jahren bestätigt. Das bedeutet am konkreten Beispiel, ein zen­tral­is­tisch-hier­ar­chisch organ­isiertes Unternehmen wird sich mit Microser­vice-Architek­turen, wo Dezen­tral­isierung, Ereignis­s­teuerung, Infor­ma­tion­saus­tausch und Entkop­plung eine große Rolle spie­len, ver­mut­lich schw­er­tun. Tech­nis­chen Schulden fall­en in dieselbe Kat­e­gorie. Steile Hier­ar­chien, Führung in Form von Kom­man­dostruk­turen anstatt Ser­vant Lead­er­ship sowie fach­liche und soziale Inkom­pe­tenz begün­sti­gen den Nährbo­den für das Wach­s­tum von TD. 

Wege aus der Schuldenfalle

Schuldeingeständnis

Ist ein Pro­jekt ein­mal in einen Zus­tand tech­nis­ch­er Über­schul­dung einge­treten, gibt es den­noch Wege hin­aus. Sie erfordern im ersten Schritt ein Schuldeingeständ­nis der Beteiligten: Prod­uct-Own­er, Devel­op­ment-Team und Pro­jek­tleitung müssen sich über ihre jew­eili­gen Anteile im Klaren sein und gemein­sam an der Lösung arbeit­en. Ein Coach kann dabei hil­fre­ich sein. Vielle­icht gibt es einen fähi­gen Scrum Mas­ter, der die Parteien dabei unter­stützt, einen gang­baren Weg zu finden.

Schadenanalyse

Sind sich PO, PL/Kunde und Dev-Team einig, kann der neg­a­tive Effekt von TD zumin­d­est abgemildert, manch­mal sog­ar beseit­igt wer­den. Jeden­falls gilt es nun, beherzt zu han­deln. Zunächst muss das Aus­maß der Tech­nis­chen Schulden umris­sen wer­den, damit die Aufwände zu ihrer Behe­bung einge­plant wer­den kön­nen. Nicht sel­ten gibt es hier­bei uner­wartete Ergeb­nisse: mehrere Wochen bis Monate an Kon­so­li­dierungsar­beit­en sind für ein Pro­jekt schw­er zu verkraften. Mut, eine der fünf agilen Tugen­den, ist hier beson­ders gefragt. In ein­er solchen Lage müssen wir uns fol­gen­des immer vor Augen hal­ten: erstens haben wir diesen Zus­tand selb­st verur­sacht, und zwar kollek­tiv auf allen Ebe­nen. Zweit­ens, wenn wir den Mut jet­zt nicht auf­brin­gen, den Zus­tand zu verbessern, wird es später noch härter.

Coaching

Eben­falls schwierig wird es, wenn die oben genan­nten Con­way-Gründe vor­liegen. Dann haben wir es mit einem echt­en Härte­fall zu tun. Unter solchen Umstän­den ist es uner­lässlich, einen erfahre­nen Coach hinzuzuziehen, der Führung und Entwick­lung miteinan­der in Ein­klang brin­gen hilft.

Vorsicht ist besser als Nachsicht: Technische Schulden einplanen

Um die Entste­hung von TD möglichst von vorn­here­in zu ver­hin­dern, gilt es, die dro­hen­den Schulden­löch­er rechtzeit­ig zu erken­nen. Ide­al­er­weise prüfen wir die beste­hende Imple­men­tierung, bevor wir mit der Weit­er­en­twick­lung begin­nen. Das schließt auch die Makroar­chitek­tur mit der Kom­mu­nika­tion zwis­chen beteiligten Sys­te­men mit ein. In diesem Fall kön­nten die Refac­tor­ing-Aufwände bere­its in der Pla­nung berück­sichtigt werden. 

Ver­säu­men wir, eine Vor­analyse durchzuführen oder ist es nicht möglich, kön­nen wir immer noch während der Entwick­lung TDs iden­ti­fizieren. Nun ist zu prüfen, wie wir damit umge­hen wollen.

Die edel­ste Option wäre, die TDs sofort zu beheben und zu akzep­tieren, dass sich der Pla­nung­shor­i­zont entsprechend nach hin­ten ver­schiebt. Das kann eine agile Pro­jek­tor­gan­i­sa­tion leicht verkraften. Im klas­sis­chen Man­age­men­tum­feld kann es jedoch passieren, dass wir damit aller­gis­che Reak­tio­nen aus­lösen. Hier wäre ein Kom­pro­miss, die TD zunächst zu akzep­tieren, um das Fea­ture – not­falls mit Workarounds um die TD herum – plan­mäßig funk­tion­al fer­tigzustellen. Nun aber müssen wir sofort ein Tick­et erstellen, um die TD anschließend so schnell wie möglich ein­pla­nen und auflösen zu kön­nen. Eine gute Release­pla­nung sollte diesen Fall auch im klas­sis­chen Umfeld abfed­ern können. 

Organisatorische Maßnahmen

Qualität mit einplanen

Organ­isatorische Maß­nah­men betr­e­f­fen alle Ebe­nen der Pro­jek­tor­gan­i­sa­tion. Am Ende jedoch läuft es darauf hin­aus, dass die Pro­jek­tleitung für das Gelin­gen oder Scheit­ern Sorge tra­gen muss. Die PL bes­timmt maßge­blich die Pro­jek­tkul­tur, und damit auch, wie mit Her­aus­forderun­gen umge­gan­gen wird, ger­ade wenn sie Geld kosten. Nicht zulet­zt bes­timmt sie, welche Qual­itäts­maßstäbe anzule­gen sind und wie die Sicherung der Soft­ware­qual­ität erfol­gen soll.

Project Staffing

Zunächst ein­mal sollte unser Pro­jekt mit fähi­gen Men­schen aus­ges­tat­tet sein: wir benöti­gen beispiel­sweise ein Prod­uct-Man­age­ment-Team und einen Führungsstab, die wis­sen, wie Soft­wa­reen­twick­lung­sprozesse funk­tion­ieren. Wir brauchen ein Devel­op­ment-Team, das auf dem Stand der Tech­nik und bere­it ist, sich stetig weit­erzuen­twick­eln. Und wir soll­ten einen Pro­jek­t­coach engagieren, beispiel­sweise einen Scrum Mas­ter, der dafür sorgt, dass die Organ­i­sa­tion der Zusam­me­nar­beit im Pro­jekt rund läuft. 

Wenn die Qual­ität­sziele gesteckt sind und das Pro­jekt gut gestafft ist, sind die Grund­la­gen geset­zt. Nun gibt es eine Rei­he von Tools, um die innere Qual­ität des Soft­ware­pro­duk­ts zu gewährleisten.

Architekturwissen vom Elfenbeinturm ins Entwicklerteam 

Eines der wichtig­sten Werkzeuge ist die Fähigkeit des Entwick­lerteams, die Soft­ware mit Hil­fe ein­er zweck­mäßi­gen Makro- und Mikroar­chitek­tur gut zu struk­turi­eren. Dadurch wird die langfristige Wart­barkeit gewährleis­tet, und Tech­nis­che Schulden kön­nen leichter ver­mieden oder behoben werden. 

Eine beliebte Falle ist hier­bei, die Soft­ware-Architek­tur als eine eigene, von der Pro­gram­mier­ar­beit getren­nte Diszi­plin zu betra­cht­en. Es emp­fiehlt sich jedoch vielmehr, dafür zu sor­gen, dass die Entwick­ler über pro­fun­des Architek­tur­wis­sen ver­fü­gen und dieses in ihrer täglichen Arbeit stetig anwen­den. Mit der dazuge­höri­gen Diszi­plin lässt sich dann die Architek­turero­sion in Gren­zen halten.

Poka-Yoke-Entwicklungsprozess – Fehler besser vorher vermeiden statt später beheben

Um durch Unacht­samkeit oder Toll­patschigkeit entste­hende Tech­nis­che Schuld von vorn­here­in zu berück­sichti­gen, emp­fiehlt es sich, den Entwick­lung­sprozess so zu gestal­ten, dass alleine dadurch die Entste­hung von TD bere­its eingeschränkt wird. Dieses Vorge­hen ist als Poka Yoke bekan­nt. Beispiel­sweise imple­men­tieren wir Domain Dri­ven Design als fes­ten Bestandteil des Prozess­es. Dadurch wird sichergestellt, dass Änderun­gen in der Fach­domäne adäquat in der Soft­ware abge­bildet wer­den. Als näch­stes sollte Clean Code gelebt wer­den. Dadurch min­imiert sich das Aufnehmen von Tech­nis­chen Schulden von selb­st. Für den pas­sion­ierten Clean Coder gehört kon­tinuier­lich­es Refac­tor­ing zu den Stan­dard­mit­teln, um ger­ade auch die Tech­nis­chen Schulden klein zu hal­ten. Eben­so sind effek­tiv durchge­führte Codere­views ein fes­ter Bestandteil der Clean-Code-Praxis.

SonarQube für statische Codeanalyse nach der SQALE-Methode

Als tech­nis­ches Tool hat sich in vie­len Pro­jek­ten Sonar­Qube etabliert, das in die Build-Pipeline inte­gri­ert wer­den kann, um mit Hil­fe von sta­tis­ch­er Code­analyse unter anderem das Aus­maß an TD zu bemessen. Dabei wird der Grad der Tech­nis­chen Schuld in Man­nta­gen beziffert. 

Allerd­ings dür­fen wir uns nicht darüber hin­wegtäuschen lassen, dass Sonar­Qube seman­tis­che Qual­ität­skri­te­rien wie Les­barkeit und Ver­ständlichkeit des Source­codes genau­so wenig messen kann wie dessen sach­liche Kor­rek­theit. Wichtige Design­prinzip­i­en wie das Sin­gle Respon­si­bil­i­ty Prin­ci­ple sind eben­falls schw­er automa­tisiert zu prüfen. Daher ist Sonar­Qube zwar eine gute Unter­stützung, sollte jedoch keines­falls als alleinige Quelle der Wahrheit dienen.

Fazit

Fassen wir zusammen:

  • Tech­nis­che Schuld entste­ht laufend während der Entwick­lung. Das ist natür­lich und ganz normal.
  • Obwohl die Tech­nis­che Schuld als Buzz­word in der Soft­wareszene hin­länglich bekan­nt ist, find­en ihre Ursachen und Auswirkun­gen wenig Beach­tung. Allzu oft wer­den sie ignoriert.
  • Die besten Pro­gram­mier­er und Architek­ten kön­nen Tech­nis­che Schulden nicht abwen­den, wenn der Entwick­lung­sprozess und/oder die Unternehmen­skul­tur wirk­same Maß­nah­men konterkarieren.
  • Ein großer Anteil tech­nis­ch­er Schulden lässt sich bere­its durch rein organ­isatorische Maß­nah­men unterbinden. Neben ein­er fähi­gen Pro­jek­t­mannschaft müssen somit auch kul­turelle und prozes­suale Voraus­set­zun­gen geschaf­fen werden.
  • Soft­ware­pro­jek­t­coach­ing ist ein pro­bates Mit­tel, um die Ver­schul­dung von Anfang an klein zu hal­ten, oder ein Soft­ware­pro­jekt aus der TD-Sack­gasse herauszuführen.

In diesem Sinne, hap­py engineering 🙂

Wikipedia: Tech­nis­che Schulden