Softwareentwicklung

Was ich durch Codex über meine eigene Art zu programmieren gelernt habe

„So hätte ich das nicht gebaut“ ist bei einem fremden Codeentwurf ein naheliegender Gedanke. Als Qualitätsurteil reicht er allerdings kaum aus. Eine andere Aufteilung kann eine wichtige Abhängigkeit übersehen haben, sie kann aber ebenso eine brauchbare Lösung sein, die lediglich von meinen Gewohnheiten abweicht. Gerade diese Unterscheidung macht die Arbeit mit Codex für meinen Blick auf das eigene Programmieren interessant.

In meiner Arbeitsweise nutze ich ChatGPT für Konzepte und Rückfragen, verdichte die Entscheidungen in einer Markdown-Spezifikation und übergebe diese an Codex für technische Analyse und Umsetzung. Dadurch werden Teile der Entwicklung voneinander getrennt, die beim eigenen Programmieren eng zusammenlaufen. An dieser Trennung lässt sich erkennen, welches Wissen ich tatsächlich formulieren kann, welche Entscheidungen erst beim Umsetzen entstehen und worauf mein Vertrauen in eine Lösung beruht.

Meine Vorstellung ist noch keine ausreichend erklärte Anforderung

Wenn ich selbst programmiere, kann ich eine ungenaue Aufgabenbeschreibung unterwegs ergänzen. Ich kenne den Zweck der Funktion und entscheide beim Schreiben, wie ein Sonderfall behandelt werden soll. Das Ergebnis kann durchaus sinnvoll sein. Trotzdem bleibt dabei leicht unsichtbar, wie viel fachliche Klärung gerade zwischen zwei technischen Handgriffen stattgefunden hat.

Die Übergabe an Codex macht diese Grenze deutlicher. Eine Beschreibung muss ohne meine gedanklichen Ergänzungen tragen. Fehlt eine Regel, hilft mir die Überzeugung wenig, dass sie doch selbstverständlich zum gewünschten Verhalten gehört. Für meine eigene Art zu programmieren folgt daraus eine unbequeme Frage: War die Aufgabe schon verstanden, oder war ich lediglich zuversichtlich, die fehlenden Entscheidungen während der Umsetzung treffen zu können?

Ein allgemeines Beispiel ist eine Funktion zum Kopieren eines Vorgangs. „Kopie anlegen“ klingt eindeutig, bis geklärt werden muss, ob der Bearbeitungsstatus mitkopiert wird. Soll eine Kopie eines abgeschlossenen Vorgangs ebenfalls abgeschlossen sein oder als neuer Entwurf beginnen? Beim eigenen Implementieren lässt sich diese Entscheidung beiläufig treffen. Im delegierten Auftrag wird sichtbar, dass hinter dem vermeintlichen Detail eine fachliche Regel steht.

Meine ausführliche Konzeptphase passt zu diesem Bedarf, darf aber selbst hinterfragt werden. Viele beantwortete Fragen helfen nur, wenn daraus ein verständlicher geltender Stand entsteht. Der Weg von einer Frage zur technischen Spezifikation verlangt deshalb auch eine Auswahl: Welche Entscheidung trägt den nächsten Schritt, und welche Einzelheit kann noch offenbleiben? Hunderte Antworten geben mir keine Garantie, dass ich die Aufgabe vollständig durchdrungen habe.

Mein Unbehagen braucht eine technische Begründung

Ein fremder Entwurf zwingt mich dazu, meine Maßstäbe genauer auszudrücken. „Zu kompliziert“ kann bedeuten, dass eine zusätzliche Abstraktion mehrere Stellen verbindet, obwohl sie unabhängig bleiben sollten. Es kann aber auch heißen, dass ich den gewählten Aufbau noch nicht kenne. Diese beiden Gründe verlangen unterschiedliche Reaktionen.

Nehmen wir an, Codex schlägt für die Kopierfunktion eine gemeinsame Hilfsfunktion vor, während ich die Logik direkt beim betreffenden Vorgang erwartet hätte. Eine brauchbare Bewertung untersucht, welche Regeln tatsächlich gemeinsam gelten und wie sich spätere Änderungen auswirken. Muss eine neue fachliche Ausnahme anschließend an mehreren Stellen berücksichtigt werden? Verbirgt die Hilfsfunktion wichtige Unterschiede? Oder macht sie eine bereits vorhandene gemeinsame Regel erstmals eindeutig?

Damit bekommt meine bevorzugte Lösung dieselbe Begründungspflicht wie der Vorschlag von Codex. Erfahrung ist ein guter Ausgangspunkt für eine Vermutung, liefert aber noch keinen Nachweis. Wenn ich nur sagen kann, dass ich etwas gewöhnlich anders mache, sollte daraus keine automatische Änderungsanforderung werden.

Für mich steckt darin ein wesentlicher Lerngewinn: Die eigenen Gewohnheiten werden überprüfbar. Manche lassen sich als sinnvolle Konvention erklären, weil sie die Orientierung im Projekt erleichtern. Andere sind persönliche Vorlieben, die mehrere gleichwertige Varianten zulassen. Diese Unterscheidung hilft mir, meine Aufmerksamkeit auf Unterschiede zu richten, die spätere Arbeit tatsächlich beeinflussen.

Beim Selberschreiben entsteht Vertrautheit, die ich genauer einordnen muss

Selbst geschriebener Code besitzt einen besonderen Vorteil: Ich erinnere mich an seinen Entstehungsweg. Ich weiß, welche Variante ich ausprobiert und weshalb ich sie verworfen habe. Diese Erinnerung erleichtert spätere Änderungen, kann aber auch das Gefühl erzeugen, die Lösung sei gründlicher verstanden, als sie tatsächlich geprüft wurde.

Bei einem delegierten Entwurf fehlt ein Teil dieser Vertrautheit. Das macht die Beurteilung zunächst aufwendiger, eröffnet aber einen nützlichen Vergleich mit meiner eigenen Arbeit. Weshalb verlange ich hier einen Nachweis, während mir bei selbst geschriebenem Code vielleicht die Erinnerung an einen erfolgreichen Versuch genügt? Der angemessene Qualitätsmaßstab sollte sich aus der Bedeutung der Änderung ergeben und unabhängig davon gelten, wer sie geschrieben hat.

Beim Kopierbeispiel könnte ich vor der Prüfung festhalten, welche Angaben übernommen werden sollen und welche ausdrücklich neu entstehen müssen. Anschließend lässt sich untersuchen, ob die Implementierung diese Erwartung erfüllt. Diese Reihenfolge schützt davor, das bereits vorhandene Verhalten nachträglich zur richtigen Lösung zu erklären. Dass Code funktioniert und seine Tests besteht, beantwortet schließlich noch nicht, ob die geprüften Erwartungen fachlich stimmen.

Mein Anspruch an das eigene Verständnis wird dadurch konkreter. Eine Erklärung nachvollziehen zu können ist ein Anfang. Weiter geht die Frage, ob ich eine veränderte Anforderung selbst einordnen kann: Wenn Kopien künftig auf ihren Ursprung verweisen sollen, welche Teile der Lösung wären betroffen und weshalb? Kann ich das am Code zeigen, besitzt mein Verständnis mehr Substanz als die Zustimmung zu einer plausiblen Zusammenfassung.

Eine Rückfrage ist auch eine Rückmeldung über meinen Auftrag

Bei delegierter Entwicklung kann eine Rückfrage verschiedene Ursachen haben. Eine bereits entschiedene Regel fehlt in der Übergabe, eine technische Untersuchung hat eine unbekannte Abhängigkeit gefunden oder der Auftrag wurde unzureichend gelesen. Für die Verbesserung meiner Arbeitsweise muss ich diese Ursachen auseinanderhalten. Jede Rückfrage pauschal als schlechte Vorbereitung zu behandeln wäre ebenso ungenau, wie sie grundsätzlich dem Werkzeug anzulasten.

Für das Kopierbeispiel wäre der Unterschied gut erkennbar. Stand bereits fest, dass jede Kopie als Entwurf beginnt, muss diese Information zuverlässig zugänglich sein. Zeigt die Repositoryanalyse dagegen, dass eine bestehende Verknüpfung einen anderen Status voraussetzt, ist neues Wissen entstanden. Eine längere ursprüngliche Beschreibung hätte diesen Befund möglicherweise gar nicht vorwegnehmen können.

Daraus ergibt sich für mich ein sinnvoller Umgang mit Korrekturen: Zunächst muss ich erklären können, weshalb eine Anpassung nötig ist. Wurde eine Vorgabe verletzt, eine bisher offene Frage entschieden oder meine eigene Erwartung verändert? Im letzten Fall sollte ich die neue Entscheidung auch als solche behandeln. Ein erst am Entwurf entwickelter Wunsch war keine heimlich schon immer gültige Anforderung.

Gerade als allein arbeitender Einzelunternehmer ist diese Unterscheidung wichtig. Ich bin Auftraggeber, fachlich Verantwortlicher und Prüfer meiner eigenen Entwicklung. Meine unterschiedlichen Perspektiven auf Software helfen dabei, Fragen zu erkennen; sie machen meine erste Vorstellung trotzdem nicht automatisch richtig. Auch meine Anforderungen müssen durch eine Untersuchung verändert werden dürfen.

Ich möchte Umsetzung abgeben und mein Urteil weiterentwickeln

Die Arbeit mit Codex führt für mich damit zu einer genaueren Vorstellung davon, was ich beim Programmieren selbst beherrschen möchte. Ich brauche genügend technische Tiefe, um Annahmen zu erkennen und die Folgen einer Änderung zu verstehen. Zugleich muss ich nicht jeden Umsetzungsschritt selbst ausführen, um eine begründete Entscheidung treffen zu können. Welche Nähe zum Code nötig ist, hängt von der Aufgabe und meinem vorhandenen Wissen ab.

Bei einem unbekannten Mechanismus kann ein eigener kleiner Versuch deshalb sinnvoll bleiben. Sein Zweck wäre, ein Verhalten selbst zu untersuchen und die eigene Vorstellung daran zu prüfen. Bei einer vertrauten Aufgabe kann dagegen eine gezielte Durchsicht ausreichen. Die Entscheidung darüber sollte sich am Lernbedarf und an den möglichen Fehlerfolgen orientieren; die bloße Verfügbarkeit eines fertigen Entwurfs beantwortet sie nicht.

Für meine weitere Arbeit möchte ich vor allem die Gründe meiner Eingriffe genauer betrachten. Wenn ich einen Vorschlag ändern lasse, sollte ich benennen können, welche Anforderung, Abhängigkeit oder Wartungsfrage dahintersteht. Bleibt als Begründung lediglich meine bevorzugte Schreibweise übrig, verdient auch die vorhandene Variante eine faire Prüfung. Umgekehrt darf eine überzeugende Erklärung keinen konkreten Einwand überdecken.

Was ich durch Codex über meine eigene Art zu programmieren lerne, liegt genau in dieser Auseinandersetzung: Mein Urteil muss außerhalb meines Kopfes verständlich werden. Eine Erwartung braucht eine Formulierung, ein Einwand einen Grund und Vertrauen eine überprüfbare Grundlage. Der Satz „So hätte ich das nicht gebaut“ darf weiterhin der Anfang einer Untersuchung sein. Interessant wird es dort, wo ich anschließend erklären kann, ob meine eigene Lösung tatsächlich besser wäre – oder ob ich gerade eine brauchbare Alternative kennenlerne.