Komplexität – Code hat keinen Wert

Komplexität – Code hat keinen Wert – wenn es niemanden gibt, der ihn versteht.

Komplexität in Softwareprojekten ist unausweichlich und seit jeher ein immer grösser werdendes Problem. Doch warum ist die Komplexität ein solches Problem und was gibt es für Ideen damit umzugehen?

Komplexität - Code hat keinen Wert

Wenn wir uns den Prozess des Programmierens vorstellen, denken wir verständlicherweise direkt an den Akt des Codeschreibens selbst. Während dies einen Grossteil der Arbeit ausmacht, so ist dies jedoch bei weitem nicht das ganze Bild. Bevor Code geschrieben wird, entsteht unvermeidbar ein mal mehr, mal weniger klares mentales Modell von Requirements, Constraints, Abläufen und Fallstricken im Kopf des Programmierers existieren, welches ihm ermöglicht den entsprechend bestmöglichen Code zu schreiben.

Ein Problem mit diesem mentalen Modell ist jedoch häufig, dass es zum Grossteil lediglich in den Köpfen der Programmierer selbst lebt und sich dort weiterentwickelt. Wenn diese Programmierer dann das Projekt verlassen, kann das oft zu Problemen führen. Knowhow geht verloren, technische Visionen verblassen, geheime Handgriffe, die die Maschinerie am Laufen lassen, geraten in Vergessenheit. Neue Programmierer, die in das Projekt dazustossen, müssen möglichst viel von diesem mentalen Modell aufnehmen und verstehen. Tun sie das nicht oder nur teilweise, oftmals eine Folge von suboptimalen Know-How Transfer, besteht die Gefahr, dass neu geschriebener Code nicht in die bestehende Codebase passt und zu Qualitäts- und Wartungsproblemen führt.

Abhilfen dafür existieren selbstverständlich, allem voran eine gute Dokumentation, ob im Code selbst oder anderweitig, sowie eine ausgebaute Testsuite. Eine «Silver Bullet» ist hier aber schwer zu finden. Dokumentation entsteht oft after the fact, kann lückenhaft sein oder nicht mehr aktuell. Tests helfen das Vertrauen in die Funktionalität und Qualität des geschriebenen Codes zu erhalten, sind aber ebenso Teil des Codes und somit auch des mentalen Modells. Sprich, man kann die Tests nicht verstehen, wenn man nicht das Modell hinter dem Programm verstanden hat.

Eine bereits erprobte Idee wäre es also, den Programmierungsprozess auf der Artefakt-Ebene nicht zu unterteilen in Dokumentation und Requirements auf der einen Seite und Code auf der anderen Seite, sondern diese beiden Aspekte direkt miteinander zu verheiraten. Hierbei gibt es schon eine ganze Reihe an Ideen und Versuchen dies zu realisieren. Generell dreht sich der Ansatz aber oft um die Definition einer gemeinsamen Sprache zur Beschreibung des Modells. Nicht selten ist diese Sprache dann Teil des Codes selbst. Bestehender Code wird damit erweitert um Contracts und Constraints des Modells selbst nicht nur zu dokumentieren, sondern auch direkt vom z.B. Compiler verifizieren und validieren zu lassen.

Ein Nachteil dieser eher codebasierten Lösungen ist jedoch die damit zusammenhängende Komplexität. Das Lernen und korrekte Anwenden dieser neuen Modell-Sprache erfordert Zeit und ein hohes Mass an Konzentration. So entstandene Artefakte sind schwierig bis unmöglich für Unwissende zu verstehen und zu erweitern. Auf der Suche nach einem Weg der Komplexität Herr zu werden hat man so noch mehr Komplexität geschaffen. In gewissen Kontexten kann dies funktionieren, in vielen anderen kann es aber auch katastrophal scheitern.

Eine natürliche Schlussfolgerung daraus ist natürlich, nicht eine textbasierte Sprache zu verwenden, sondern sich möglichst an Bildsprachen zu orientieren. Auch hier gibt es bereits einige Versuche, oftmals schiessen diese Lösungen aber etwas über das Ziel hinaus und zu viel des auszuführenden Codes wird generiert. Dies macht es zum einen wieder umso komplexer, je mehr man mit der Bildsprache ausdrücken will, als auch macht es die Arbeit der Programmierer wiederum nicht unwesentlich anstrengender. Mit zu viel generierten Code auf Dauer interfacen zu müssen, macht den Entwicklungsprozess auf mehrere Arten unangenehm und langsam.

Was wäre also, wenn man aus den Fehlern der vorhergegangenen Lösungen lernt und einen neuen Vorstoss wagt. Somit keine neue Sprache schaffen, dessen Grammatik und Syntax erst aufwendig einstudiert werden muss, sondern auf simple und bekannte Grafiken wie UML setzten. Anstatt No-Code-mässig versuchen, den gesamten Programmierprozess zu abstrahieren, lieber auf kleine und contract-basierte Generierungen setzten, mit denen ein Entwickler dann simpel interagieren kann. Mit wenig Aufwand könnte hier einiges geschaffen werden, lediglich versuchen müsste man es.

Autor

Felix Isensee, Software Developer

Felix liebt nicht nur komplexe Problemstellungen in der Softwarearchitektur und -entwicklung zu lösen, sondern ist auch passionierter Schachspieler und entzückt die Runde ab und zu mit lässigen Gittarenklängen.