80 Punkte von GN⁺ 2025-07-15 | 2 Kommentare | Auf WhatsApp teilen
  • Die Balance zwischen Perfektion und Tempo ist nicht einfach, aber angemessene Qualität je nach Situation und das Einhalten von Fristen sind wichtig
  • Es ist effektiv, zuerst einen Entwurf (Rough Draft) zu entwickeln und anschließend die Codequalität zu verbessern
  • Wenn man Anforderungen lockert oder überzogene Anforderungen reduziert, lassen sich Tempo und Effizienz steigern
  • Man sollte Ablenkungen vermeiden, häufig in kleinen Einheiten committen und sich angewöhnen, sich auf das Wesentliche zu konzentrieren
  • Es gibt konkrete Skills, die bei schneller Entwicklung helfen, etwa Code lesen, Datenmodellierung, Scripting, Debugging und die Ausrichtung auf pure Funktionen

„Wie gut muss Code sein?“ – Qualitätsmaßstäbe und realistische Entscheidungen

  • Am Anfang wollte ich, dass jeder Code perfekt ist
    • Ich träumte von Code, bei dem jede Funktion gründlich getestet ist, Variablennamen elegant sind, Abstraktionen klar wirken und es überhaupt keine Bugs gibt
  • Mit der Zeit lernte ich jedoch die Realität: „Es gibt keine richtige Antwort.“
    • Je nach Situation wird eine andere Codequalität verlangt
    • 24-Stunden-Game-Jam: Fertiger Code muss nicht unbedingt sauber oder bugfrei sein
      • Wichtiger ist es, innerhalb der begrenzten Zeit etwas Funktionsfähiges zu liefern
    • Software für Herzschrittmacher: Ein einziger Fehler kann Menschenleben gefährden
      • Daher sind höchste Zuverlässigkeit und Sicherheit unverzichtbar
  • Die meisten Projekte liegen zwischen diesen beiden Extremen
    • Manche Unternehmen verlangen schnelle Lieferung und tolerieren dafür einige Bugs
    • Manche Projekte verlangen hohe Qualität, haben aber einen großzügigen Zeitplan
    • In der Praxis ist es wichtig, dieses Gleichgewicht richtig einzuschätzen
    • Man sollte zuerst verstehen, was im Team als „gut genug“ gilt
      • Also gemeinsam prüfen, welche Bugs akzeptabel sind und an welchen Stellen Unvollkommenheit in Ordnung ist
  • Mein persönlicher Maßstab ist
    • „8 von 10 Punkten Qualität innerhalb der Frist erreichen“
      • Der Code erfüllt seinen Zweck zuverlässig, hat keine kritischen Probleme, aber kleinere Schwächen können bleiben
      • Das Wichtigste ist, fristgerecht zu liefern
    • Auch dieser Maßstab wird jedoch je nach Projektkontext flexibel angepasst
      • Manchmal lohnt es sich, Perfektion anzustreben, auch wenn sich der Zeitplan verschiebt
      • Und manchmal ist es wertvoller, etwas mit geringerer Vollständigkeit erst einmal schnell abzuschließen

Rough Drafts – praktische Nutzung und Vorteile von Entwürfen und Prototyping

  • Auch in der Softwareentwicklung ist es wie beim Schreiben sehr nützlich, einen Entwurf (rough draft, spike, walking skeleton) zu erstellen
  • Ich setze so schnell wie möglich einen Rough Draft um und entwickle ihn danach zu einer ausgereiften Lösung weiter
  • Mein Rough-Draft-Code ist voller Bugs: fehlschlagende Tests, überall TODO-Kommentare, unbehandelte Ausnahmen, exzessive print-/log-Ausgaben,
    keine Performance-Überlegungen, WIP-Commit-Messages, unnötige zusätzliche Pakete, duplizierter Code, Hardcoding, Linter-Warnungen – also ziemlich chaotisch
  • Das wirkt ineffizient, aber das Ziel ist, einen Zustand zu erreichen, in dem man zumindest das Wesen des Problems versteht
  • Natürlich wird solcher Entwurfscode nicht direkt in die finale Auslieferung übernommen; vor einem echten Release wird er unbedingt bereinigt
    (Es gibt zwar manchmal Druck im Team, Entwurfscode unverändert auszuliefern, aber ich wehre mich nach Möglichkeit dagegen)
  • Hauptvorteile des Rough-Draft-Ansatzes

    • „Unknown unknowns“ werden früh sichtbar
      • Es ist viel besser, unbekannte Hindernisse früh im Prototyping zu entdecken, als sie erst nach Fertigstellung in Code zu finden, der dann weggeworfen wird
    • Viele Probleme verschwinden beim Schreiben des Prototyps ganz von selbst
      • Langsame Funktionen oder eine falsche Struktur werden später oft ohnehin überflüssig, was unnötige Arbeit spart
      • Man muss also nicht zu früh zu viel Energie in Optimierung oder Tests stecken
    • Es erhöht die Konzentration
      • Unnötiges Refactoring, Grübeln über Namen oder das Reparieren anderer Codebasen werden vermieden,
        sodass man sich ganz auf das aktuell zu lösende Problem konzentrieren kann
    • Es verhindert unnötige frühe Abstraktion
      • Wenn man zuerst schnell eine funktionierende Lösung baut, versucht man seltener, unnötige Abstraktionen für die Zukunft einzuziehen
      • So konzentriert man sich auf das unmittelbare Problem und vermeidet unnötig komplexe Designs
    • Klarere Kommunikation des Fortschritts
      • Ein Rough Draft macht es möglich, genauer abzuschätzen, wie viel noch übrig ist
      • Man kann früh etwas Lauffähiges zeigen, wodurch Feedback von Stakeholdern und Richtungsänderungen schneller erfolgen
  • Praktische Arbeitsweise mit Rough Drafts

    • Schwer rückgängig zu machende Entscheidungen (binding decisions) müssen in der Entwurfsphase unbedingt erprobt werden
      • Zum Beispiel: Sprache, Framework, DB-Schema und andere große Richtungsentscheidungen sollten früh überprüft werden
    • Alle Behelfslösungen/Hacks müssen mit TODO-Kommentaren oder Ähnlichem dokumentiert werden
      • In der polish-Phase kann man sie mit git grep TODO usw. vollständig erfassen und nacharbeiten
    • Top-Down entwickeln
      • Zuerst ein Scaffold für UI, API usw. entsprechend der Nutzung aufbauen; interne Logik darf dabei gern hardcodiert oder provisorisch sein
      • In der Praxis ändern sich untere Ebenen oft, sobald UI und Nutzungserlebnis feststehen, daher ist die Implementierung von oben nach unten vorteilhaft
      • Erst die unteren Ebenen perfekt zu bauen und dann an die oberen anzupassen, ist ineffizient
    • Kleine Änderungen als separate Patches trennen

Der Versuch, Anforderungen zu verändern

  • Betont wird das Prinzip: Weniger tun ist schneller und einfacher
  • In der Praxis überlege ich bei einer Aufgabe immer, ob sich die Anforderungen lockern lassen
    • Beispielfragen:
      • Lassen sich mehrere Screens zu einem zusammenfassen?
      • Muss man knifflige Edge Cases wirklich alle behandeln?
      • Wenn 1000 Eingaben unterstützt werden sollen – reichen vielleicht auch 10?
      • Kann statt einer vollständigen Lösung ein Prototyp genügen?
      • Kann man dieses Feature vielleicht ganz weglassen?
  • Dieser Ansatz erhöht Entwicklungsgeschwindigkeit und Effizienz
  • Auch die Organisationskultur versuche ich schrittweise in ein etwas langsameres und vernünftigeres Tempo zu lenken
    • Plötzliche große Veränderungsforderungen funktionieren selten gut
    • Stattdessen verändert man die Stimmung nach und nach mit schrittweisen Vorschlägen und anderen Formen der Diskussion

Ablenkung im Code vermeiden

  • Nicht nur äußere Faktoren wie Benachrichtigungen oder Meetings, sondern auch Abschweifen während der eigentlichen Codearbeit ist ein großes Hindernis
  • Mir passiert es oft, dass ich beim Beheben eines Bugs plötzlich an völlig irrelevanten Stellen arbeite und die eigentliche Aufgabe liegen bleibt
  • Zwei konkrete Methoden helfen dabei:
    • Einen Timer setzen: Für jede Aufgabe ein Zeitlimit festlegen und beim Alarm den aktuellen Fortschritt überprüfen
      • Das wirkt als Warnsignal, wenn etwas länger dauert als erwartet
      • Wenn man zusammen mit dem Alarm ein git commit macht, entsteht zusätzlich ein kleines Erfolgserlebnis
      • (Diese Methode hilft auch beim Üben realistischer Zeitschätzungen)
    • Pair Programming: Gemeinsames Arbeiten verringert unnötige Abschweifungen und hilft, die Konzentration zu halten
  • Für manche Entwickler ist das Vermeiden solcher Ablenkungen ganz natürlich, für mich braucht es bewusste Fokussierung und eingeübte Gewohnheiten

Änderungen in kleinen Einheiten, klein aufteilen

  • Früher hatte ich einen Vorgesetzten, der große Patches und weitreichende Änderungen förderte,
    aber ich habe erlebt, dass das in der Praxis sehr ineffizient ist
  • Kleine, fokussierte Diffs sind fast immer besser
    • Sie verursachen weniger Aufwand beim Schreiben
    • Code Reviews werden einfacher und schneller, die Ermüdung bei Kolleg:innen sinkt, und meine Fehler werden leichter entdeckt
    • Wenn Probleme auftreten, ist ein Rollback einfacher und sicherer
    • Weil der Änderungsumfang auf einmal klein bleibt, sinkt auch das Risiko neuer Bugs
  • Auch große Features oder Erweiterungen entstehen durch die Summe kleiner Änderungen
    • Beispiel: Wenn ein neuer Screen nötig ist, trennt man Bugfixes, Dependency-Upgrades und Feature-Erweiterungen jeweils in eigene Patches
  • Es wird betont, dass kleine Änderungen helfen, Software schneller und mit höherer Qualität zu entwickeln

Konkrete Skills, die bei schneller Entwicklung wirklich geholfen haben

Das bisher Gesagte ist eher abstrakt, aber es gibt auch konkrete praktische Skills, die für schnelle Entwicklung tatsächlich wirksam sind

  • Code lesen (Reading code): die wichtigste Entwicklerfähigkeit, die ich bisher erworben habe

    • Wer bestehenden Code gut interpretieren kann, dem fällt Debugging viel leichter
    • Bugs oder schlechte Dokumentation in Open-Source- oder Third-Party-Bibliotheken verlieren viel von ihrem Schrecken
    • Durch das Lesen fremden Codes lernt man enorm viel, und es hilft direkt dabei, die allgemeine Problemlösungskompetenz zu verbessern
  • Datenmodellierung (Data modeling): Auch wenn es Zeit kostet, ist es wichtig, das Datenmodell sauber zu entwerfen

    • Ein schlecht entworfenes Datenbankschema führt später zu vielen Problemen und teuren komplexen Änderungen
    • Systeme so zu entwerfen, dass ungültige Zustände gar nicht erst darstellbar sind, reduziert Bugs an der Wurzel
    • Das gilt umso mehr, wenn Daten gespeichert oder mit externen Systemen ausgetauscht werden
  • Scripting: Die Fähigkeit, mit Bash, Python usw. kurze Skripte schnell zu schreiben, maximiert die Entwicklungseffizienz

    • Ich nutze das jede Woche mehrfach für Automatisierung wie Markdown-Sortierung, Datenbereinigung oder das Finden doppelter Dateien
    • Bei Bash verhindern Tools wie Shellcheck Syntaxfehler schon im Vorfeld
    • Für Aufgaben, die nicht robust sein müssen, kann man mit Hilfe eines LLM schnell zu einem Ergebnis kommen
  • Nutzung von Debuggern: Debugger zu verwenden ist essenziell für schnelle Problemdiagnose und das Verständnis von Codeflüssen – etwas, das mit print/log allein nicht möglich ist

    • Die eigentliche Ursache komplexer Bugs findet man deutlich schneller
  • Der richtige Zeitpunkt für Pausen: die Gewohnheit, bei Blockaden bewusst Pause zu machen

    • Ein Problem, das man über lange Zeit nicht lösen kann, ist nach fünf Minuten Pause erstaunlich oft sofort lösbar
    • Das ist auch wichtig für die Effizienz der Konzentration
  • Orientierung an pure functions und immutable data: funktionale Programmierung: Wenn man pure Funktionen und immutable data bevorzugt,

    • sinkt die Zahl der Bugs, die Last der Zustandsverfolgung nimmt ab, und Klarheit sowie Vorhersagbarkeit des Codes steigen
    • Oft ist das einfacher und wirksamer als der Entwurf komplexer Klassenhierarchien
    • Es ist nicht immer möglich, aber ich ziehe diesen Ansatz grundsätzlich zuerst in Betracht
  • Nutzung von LLMs (Large Language Models): LLMs (z. B. ChatGPT) haben zwar auch Nachteile, bringen aber bei repetitiven oder automatisierbaren Entwicklungsaufgaben enorme Geschwindigkeitsvorteile

    • Ich nutze sie aktiv, nachdem ich gut verstanden habe, wie man LLMs in den eigenen Codefluss einbindet und wo ihre Grenzen liegen
    • Dabei orientiere ich mich auch an Erfahrungen, Tipps und Beispielen aus der Community
      All diese Skills habe ich über lange Zeit immer wieder geübt, und sie sind zu einem großen Vermögenswert für schnelle Entwicklung geworden

Zusammenfassung

  • Die wichtigsten Lehren, die ich beim schnellen Entwickeln von Software gewonnen habe, sind folgende
    • Für jede Aufgabe klar erfassen, welches Maß an Codequalität nötig ist
    • Schnell einen Rough Draft schreiben, um die Gesamtstruktur festzulegen
    • Immer nach Möglichkeiten suchen, Anforderungen zu lockern
    • Sich nicht von Ablenkungen treiben lassen und die Konzentration aufrechterhalten
    • Änderungen klein und häufig committen und große Patches vermeiden
    • Konkrete praktische Skills (Code lesen, Datenmodellierung, Debugging, Scripting usw.) kontinuierlich trainieren
  • All das wirkt selbstverständlich, aber es hat lange gedauert, bis ich diese Lehren tatsächlich gewonnen habe

2 Kommentare

 
nicewook 2025-07-15

Da ist viel Nachvollziehbares dabei.
Auch die Kommentare sind gut, aber wenn jemand das so ordnet und formuliert, also gewissermaßen den Rahmen dafür schafft, dann habe ich das Gefühl, dass es durch Widerspruch, Zustimmung und Ergänzungen noch vollständiger wird.

PS: Den Ausdruck „langweilige Technologie“ sehe ich in letzter Zeit häufig; auf Englisch ist das dann wohl boring technology.

 
GN⁺ 2025-07-15
Hacker-News-Kommentare
  • In den letzten Jahren habe ich gelernt, wie man schnell und dennoch ausreichend robuste Systeme baut

    • Ich habe gelernt, dass es wichtig ist, ein einzelnes Tool wirklich tief zu beherrschen. Etwas, das ich gut kenne, ist viel effizienter als ein Tool, das oberflächlich besser geeignet wirkt. Tatsächlich ist Django für die meisten Projekte genau die richtige Wahl

    • Manchmal habe ich ein Projekt mit der Sorge begonnen, Django könnte zu schwergewichtig sein, aber am Ende ist das Projekt weit über die ursprüngliche Absicht hinausgewachsen. Ich habe zum Beispiel eine Status-Page-App gebaut und schnell gemerkt, dass der Versuch, an Djangos Grenzen vorbeizuplanen, ineffizient ist

    • Bei den meisten Apps, die gut zu Django-Modellen passen, ist das Datenmodell der Kern. Selbst bei einem Prototypen steigen Kosten und Schwierigkeit später exponentiell, wenn man das Refactoring des Datenmodells aufschiebt

    • Die meisten Apps brauchen weder eine Single-Page-App noch ein schwergewichtiges Frontend-Framework. Für einige Teile mag das zutreffen, aber für 80 % der Seiten reichen klassische Django-Views aus. Für den Rest kann man AlpineJS oder HTMX in Betracht ziehen

    • In den meisten Fällen ist Eigenentwicklung einfacher. Mit Django lassen sich CRM, Status-Page, Support-System, Sales-Prozesse und mehr sehr schnell bauen. Das geht viel schneller als die Integration eines kommerziellen CRM.

    • Wähle möglichst langweilige, gewöhnliche Technik. Mit Python/Django/Postgres lässt sich fast alles lösen. Kubernetes, Redis, RabbitMQ, Celery usw. kann man vergessen. Alpine/HTMX ist eine Ausnahme, weil man damit den Großteil des JS-Stacks vermeiden kann

    • Redis und Kubernetes sind für mich die „langweilige Technik“ des Jahres 2025. Beide sind extrem stabil, ihr Einsatzzweck ist klar, und ihre Nachteile sind längst gut bekannt, was sie sehr vertrauenswürdig macht. Ich bin persönlich ein Fan von beiden. Sie tun genau das, was ich will, und deshalb vertraue ich ihnen sehr

    • Ich mag Django ebenfalls wirklich sehr. Man kann damit ein Projekt extrem schnell starten und deployen

      • Bei der Arbeit nutzen wir Go, und für denselben API-Endpunkt wird der Code zehnmal länger. Jedes zusätzliche Feature wie Query-Parameter oder Paging macht den Code noch länger. Mit einem Berechtigungsmodell wird es noch schlimmer
      • Natürlich gibt es auch große Performance-Unterschiede, aber in der Praxis bestimmen DB-Queries den Großteil der Performance. Auch in Python ist es schnell genug
    • Wenn man wirklich auf „langweilige Technik“ setzt, sollte man sogar bei Postgres noch einmal nachdenken

      • Sqlite skaliert viel weiter, als viele denken. Gerade für lokale Entwicklung oder isolierte CI-Instanzen gilt das, und für kleine Apps kann es sogar in Produktion ausreichend sein
    • Ich verwende Celery in Django-Projekten ziemlich oft. Mir gefällt die Komplexität nicht, aber in einer PaaS-Umgebung ist es oft noch die am wenigsten schmerzhafte Wahl

      • Ich starte jedes Mal mit dem Vorsatz, es ohne Celery zu versuchen, aber am Ende stoßen HTTP-getriggerte Jobs auf Timeouts und ich lande doch wieder bei Celery. An diesem Punkt muss man zwischen Threads, Cronjobs (vor allem auf PaaS schwierig) und Celery wählen. Ich bin neugierig, wie andere damit umgehen
    • Die Aussage „Die meisten Apps brauchen keine SPA oder schwergewichtigen Frontend-Frameworks“ scheint mit dem Rat „Beherrsche ein Tool in der Tiefe“ zu kollidieren

      • Ich baue jede Seite mit React. Nicht weil ich unbedingt eine SPA brauche, sondern weil irgendwann doch Client-seitiges State-Management nötig wird und ich es bequemer fand, von Anfang an alles in React zu bauen. Anfangs wirkt das schwergewichtig, am Ende ist es aber effizienter
  • Wenn man Code als groben Entwurf hinterlässt, wird er oft vom Management genau so als „Final Version“ ausgeliefert

    • Deshalb schreibe ich von Anfang an robusten Code. Sogar Test-Harnesses mache ich fast auf Deployment-Niveau robust

    • Entscheidend ist, sehr hochwertige Module zu bauen. Teile, die sich sehr wahrscheinlich nicht ändern oder bei Änderungen massive Probleme verursachen würden, isoliere ich in eigenständige Module und importiere sie als Abhängigkeiten

    • Dank solcher Module kann ich neue Apps sehr schnell entwickeln und dabei die Qualität konstant hoch halten

    • Beispiele aus meiner eigenen Praxis sind RVS_Checkbox, ambiamara, RVS_Generic_Swift_Toolbox usw.

    • Ich habe eine Frage: Ist es in Swift üblich, als Kommentar-Marker Code-Muster wie "* ##################################################################" zu verwenden?

      • Im Quellcode fällt das visuell sehr stark auf
  • Je nach Projektgröße ändert sich der Ansatz stark

    • Für persönliche Projekte oder kleine Teams ist „schnell und grob“ oft optimal. Das ist eine Stärke kleiner Entwicklungsvorhaben

    • In kleinen Setups lassen sich Bugs schnell beheben, und alle Teammitglieder verstehen praktisch den gesamten Code sehr gut

    • Mit wachsender Größe explodieren die Kosten für Architekturfehler oder Bugfixes. Die Architektur wird zwangsläufig komplex, und große Refactorings sind faktisch unmöglich. In so einer Umgebung muss Korrektheit Schritt für Schritt oberste Priorität haben

    • Kontext ist wirklich entscheidend. Was genau „groß“ bedeutet, kann variieren, aber nach meiner Erfahrung war es immer richtig, APIs zwischen Apps früh abzustimmen, damit Frontend und Backend beide schnell arbeitsfähig werden

      • Es ist effektiv, so früh wie möglich auf einen Produktionsserver zu deployen, um Tests und teamübergreifende Probleme sichtbar zu machen
      • Der Autor scheint sich auf den Code selbst zu konzentrieren, aber ich denke, in großen Teams ist dieser Punkt noch wichtiger
      • Architekturen mit hierarchischen Abhängigkeiten zwischen Teams halte ich allerdings für keine gute Idee, auch wenn sie in der Praxis oft vorkommen
    • In solchen Situationen sollte man das System kleiner halten. Alle wünschen sich ein riesiges System, aber tatsächlich braucht man es meist nicht

  • Es heißt oft: „Bei einem 24-Stunden-Game-Jam muss man sich nicht um Codequalität kümmern“, aber nach den meisten Hackathons und Code-Reviews, die ich erlebt habe, lieferten die besten Teams auch bei Codequalität und rudimentärer Testumgebung gute Arbeit ab

    • Die beiden Aussagen oben (für Geschwindigkeit muss man Codequalität opfern vs. die besten Teams haben höhere Qualität) widersprechen sich eigentlich nicht. Gute Teams haben sich nicht zwangsläufig nur an sauberem Code festgebissen

    • Im Game-Jam-Beispiel kann eine zu starke Fixierung auf sauberen Code dem Gesamtergebnis sogar schaden. Systeme wie UE blueprint zeigen, warum das Ergebnis manchmal Vorrang vor „Sauberkeit“ haben muss

    • Manche beurteilen die „Sauberkeit“ von Code insgesamt, andere bewerten die Detailkosten und den Nutzen unnötiger Codeverbesserungen

      • Meiner Meinung nach erzielen Letztere in jeder Situation deutlich bessere Ergebnisse, ob im Hackathon oder bei hochstabilem Produktivcode
  • Anders als die Aussage „Beim Prototyping tauchen unerwartete unknown unknowns auf“ sehe ich, wenn ich etwas zum ersten Mal anfasse, fast immer nur die Vorteile und kaum die Nachteile

    • Tatsächlich treten die echten Probleme, also die unknown unknowns, erst in der Phase der eigentlichen Fertigstellung auf: Edge Cases, benutzerfreundliche Fehlermeldungen, Entfernen von Seiteneffekten usw.

    • Wahrscheinlich entstehen die unknown unknowns, die ich erlebe, eher aus Tools, Frameworks oder Libraries selbst, während der Autor unknown unknowns im Problemraum meint

    • Es stimmt auch, dass ein rough draft nicht zu rough sein darf. Wenn man bei Dingen schludert, über die man nicht hinwegsehen sollte, treten dort die echten Probleme auf.

      • Wenn Rallyefahrer zum Beispiel die Streckenrecherche zu oberflächlich machen, können sie unerwarteten Gefahren ausgesetzt sein, etwa einer Bodenwelle vor einer Kurve
    • Wenn man Tools für den Eigengebrauch baut, kann man sie ziemlich grob zusammenzimmern und trotzdem gut verwenden; auch wenn diese schnell gebauten Tools voller Schwachstellen sind, verursacht das oft keine Probleme

  • In der heutigen Tech-Branche mit häufigen Restrukturierungen ist das die größte Bedrohung für Softwarequalität und Produktivität von Engineers

    • Die Angst vor Entlassungen und der Druck, schnell Ergebnisse zu liefern, zerstören Kreativität und Experimentierfreude und führen zu Burnout

    • Alle werden von Hype-Themen wie AI mitgerissen, und es entsteht eine Umgebung, in der man nicht einmal mehr Kritik üben kann

    • Das ist ein dringlicheres Problem als automatisches Coding mit LLMs

    • Die größte Bedrohung für Softwarequalität war schon immer, dass Konsumenten nicht für Qualität bezahlen

      • Selbst wenn es eine Nutzergruppe gibt, die Qualität „spürt“, reicht das nicht aus, um ein neues Produkt allein über Qualität erfolgreich zu machen
      • In anderen Branchen, etwa bei Autos oder Haushaltsgeräten, unterscheiden sich die Preise nach Qualität, bei Software ist das nicht so
    • Lock-in auf Programmierebene ist in Wirklichkeit viel zerstörerischer als SaaS-Lock-in

      • Der Hardwaremarkt wird bereits von wenigen Akteuren dominiert, und bald werden dieselben Unternehmen auch die Software monopolisieren
      • Am Ende bleiben statt Computerprogrammierern nur noch LLM-Prompter übrig
  • In schnellen Zyklen wie einem 24-Stunden-Game-Jam habe ich eher das Gefühl, dass schlechter Code tödlich ist

    • Je sauberer der Code ist, desto weniger Fehler passieren, desto geringer ist die Belastung des Arbeitsgedächtnisses, und desto leichter sind gewünschte Änderungen, Feature-Ergänzungen oder Problemlösungen kurz vor Schluss

    • Was 24-Stunden-Projekte am häufigsten scheitern lässt, ist nicht, dass man langsam codiert hat, sondern dass man sich selbst in eine Ecke manövriert oder von unvorhersehbaren Problemen aus der Bahn werfen lässt

    • Das heißt natürlich nicht, dass man jeden Bug finden muss. Aber bei niedriger Grundqualität wird das Projekt insgesamt zu einer anstrengenden Erfahrung

    • Dieses Prinzip gilt auch für Projekte mit mehr Zeit. Nur weil man mehr Zeit hat, ist schlampiges Arbeiten nicht besser

    • Wenn guter Code zur Gewohnheit wird, kann man Qualität ohne Zusatzkosten sicherstellen. Und selbst wenn es mehr Zeit kostet, ist es am Ende lohnend

    • Ich sehe das genauso. Ich habe mehrfach an Game Jams teilgenommen, und „schlampiger Code“ ist nur in den letzten ein bis zwei Stunden vor Abgabe akzeptabel und nur in Dateien, die sonst niemand mehr anfasst

      • Gemeinsame Logik aufzuräumen und Code zu ordnen dauert überraschend wenig Zeit
      • Realistisch gesehen sind Bugs aus unsauberem Code viel gravierender und riskanter als die Zeit, die man sich durch das Nicht-Aufräumen spart
      • Bei ähnlichen, aber unterschiedlichen Features (z. B. Fade-out von Licht vs. Fade-out von Farbe) lasse ich allerdings lieber duplizierten Code stehen. Die Anforderungen driften dort leicht auseinander
    • Um schnell und guten Code zu schreiben, hilft am Ende nur, sehr viel zu schreiben

      • Wiederholte Arbeit kann lästig sein, ist aber tatsächlich effektiv
      • Wer innerhalb der verfügbaren Zeit sauber coden kann, hat diesen Code einfach schon oft genug geschrieben
    • Unter Zeitdruck kümmere ich mich nicht um schicke Dinge wie einen fancy Asset-Loader, sondern nehme einfach statische Dateien

      • Wenn Pfadsuche nötig ist, erledige ich das einfach mit etwas Einfachem wie breadth first search
      • Das ist kein „schlechter Code“, sondern einfach ein Behelf und eine schnelle Lösung
      • Natürlich kann es Regeln geben, die solche Module verbieten; dann muss man sich an die Vorgaben halten
    • Ich glaube, die Annahme „Guten Code zu schreiben dauert länger“ ist ein Missverständnis. Ab einem gewissen Anspruchsniveau steht guter Code der Geschwindigkeit nicht im Weg

  • Der Maßstab dafür, was „good enough“ ist, unterscheidet sich von Team zu Team, und das war in meiner Karriere eine der größten Konfliktquellen

    • Leute aus Big Tech beklagen unzureichende Tests, Leute aus Startups beklagen zu geringe Geschwindigkeit

    • Es wäre hilfreich, den Maßstab für „good enough“ klar zu dokumentieren und im Team zu teilen

    • Genau dafür gibt es ein Team Charter, also ein Dokument darüber, „wie wir arbeiten“

  • Einer der wichtigen Faktoren, die im Artikel nicht erwähnt wurden, ist die mit der Zeit nachlassende Entwicklungsgeschwindigkeit

    • Wenn Projekt und Team wachsen, wird die Entwicklung zwangsläufig langsamer

    • Selbst wenn es kurzfristig ein wenig Geschwindigkeit kostet, muss man früh Tests, Dokumentation, Entscheidungsprotokolle, Agile-Meetings usw. vorbereiten, damit die Entwicklung langfristig weniger stark abbremst

    • Wenn man Dinge wie Observability oder eine testfreundliche Code-Struktur nicht früh vorbereitet, hat das später massive negative Folgen

    • Ich bin Solo-Entwickler, spüre aber ebenfalls die Bedeutung von Entscheidungsprotokollen, Tests und Dokumentation

      • Ich führe eine laufende Entwurfsdokumentation, die ich „Labornotizbuch“ nenne; sie bildet später die Grundlage für Tests und Dokumentation
      • Mit so einem Labornotizbuch kann man auch bei spätem Start schneller bessere Dokumentation schreiben. Tests helfen außerdem dabei zu prüfen, ob sich das Design verändert hat
      • Bei sehr kurzlebigen Einmal-Tools kann man einfach loslegen, aber bei Systemen, die lange genutzt werden, ist es letztlich vernünftig und wartbar, auch wenn es langsamer geht, zuerst ein solides Fundament zu bauen
      • Das ist vielleicht keine populäre Meinung, aber Design funktioniert am besten erst auf Papier und dann digital
  • Das ist auch für mich ein vertrautes Muster. Ich beginne mit einem rough draft oder mit einem kleinen Stück Code zur Ideenvalidierung, das andere Skriptsprachen oder manuelle Abläufe zusammenbindet

    • Nicht selten komme ich dadurch sogar zu dem Schluss: „Wir müssen das, was wir ursprünglich wollten, eigentlich gar nicht bauen“
    • Ich kann mich sehr mit dem Gedanken identifizieren, beim Coden die Konzentration zu verlieren. Beim Aufräumen gerät man leicht in ein Rabbit Hole, die Commits werden zu groß und für Kollegen schwer reviewbar. Oft verwerfe ich dann alles und fange kleiner und zielgerichteter noch einmal an
    • Manchmal kann man brauchbare Teile separat herauslösen und in einem anderen PR einreichen
    • Das Business will schnell Ergebnisse, und die Trade-offs im Code versteht es meist erst dann, wenn sich so viel Debt angesammelt hat, dass die Entwicklung extrem langsam wird
    • Entscheidend ist die Balance, und für jedes Projekt kann ein anderer Maßstab gelten
    • Deshalb helfen kleine, fokussierte und einfache Änderungen in hoher Frequenz
    • Allerdings ist es nicht so leicht, eine große Lösung in kleine Teile zu zerlegen, wie man denkt
    • Ich sehe oft Commits mit völlig unzusammenhängendem und noch gar nicht genutztem Code, der mit „das brauchen wir später“ begründet wird. Ein Jahr später ist das wegen geänderter Prioritäten oder Personalwechsel meist alles nutzloser Code, und niemand kennt den damaligen Plan noch