qpc8

Loading...

Warum die meiste Individualsoftware nach 12 Monaten unwartbar wird

Die Muster, die funktionierende Software in technische Schulden verwandeln. Was schiefgeht, warum es passiert und wie man Systeme baut, die wartbar bleiben.

Kevin Kulcsar··9 min read

Die Zwoelf-Monats-Klippe

Die meiste Individualsoftware funktioniert beim Launch perfekt. Die Features entsprechen der Spezifikation. Der Kunde ist zufrieden. Alle gehen zum naechsten Projekt ueber.

Zwoelf Monate spaeter muss sich etwas aendern. Ein neues Feature. Eine Integration. Eine Korrektur fuer einen Workflow, der nicht mehr zur Realitaet passt. Und ploetzlich dauert, was Tage dauern sollte, Wochen. Was 500 EUR kosten sollte, kostet 5.000 EUR. Einfache Aenderungen zerstoeren nicht zusammenhaengende Funktionalitaet.

Das ist kein Pech. Es ist vorhersehbar. Und es wird fast immer durch dieselben Muster verursacht.

Muster 1: Keine Dokumentation (Das "Ich-hab-alles-im-Kopf"-Problem)

Der Entwickler, der das System gebaut hat, verstand es perfekt. Jede Entscheidung ergab im Kontext Sinn. Die Architektur war in seinem Kopf elegant.

Dann wechselte er zu einem anderen Projekt. Oder verliess das Unternehmen. Oder vergass schlicht die Details, nachdem er an anderen Dingen gearbeitet hatte.

Was verloren geht:

  • Warum bestimmte Architekturentscheidungen getroffen wurden
  • Was von was abhaengt (die versteckte Kopplung)
  • Wie man die Entwicklungsumgebung einrichtet
  • Was der Deployment-Prozess tatsaechlich erfordert
  • Welche Teile fragil sind und warum
Das Ergebnis: Jede Aenderung erfordert Archaeologie. Neue Entwickler verbringen Stunden mit Verstehen, bevor sie aendern koennen. Sie nehmen Aenderungen vor, die sicher erscheinen, aber Annahmen brechen, von deren Existenz sie nichts wussten.

Die Loesung: Dokumentation ist nicht optional. Mindestens: eine README, die das Setup erklaert, eine Architektururebersicht und Inline-Kommentare fuer nicht offensichtliche Entscheidungen. Das kostet vielleicht 10% mehr Zeit bei der Entwicklung, spart aber 500% bei der Wartung.

Muster 2: Feature-Creep ohne Refactoring

Version 1 hatte drei Features. Die Architektur unterstuetzte drei Features wunderbar.

Dann wuenschte der Kunde ein viertes Feature. Es passte nicht ganz zur Architektur, aber die Deadline war knapp, also wurde es drangebaut. Dann ein fuenftes. Dann ein sechstes. Jede Erweiterung fuegte einem Fundament Komplexitaet hinzu, das dafuer nie ausgelegt war.

Was passiert:

  • Funktionen wachsen von 20 Zeilen auf 200 Zeilen
  • Dateien werden zu Abladestellen fuer lose zusammenhaengenden Code
  • Zustandsverwaltung wird verstreut und unberechenbar
  • "Temporaere" Workarounds werden zu permanenten Einrichtungen
  • Neue Features erfordern die Aenderung von 15 Dateien statt 2
Das Ergebnis: Das System wird zum Minenfeld. Erfahrene Entwickler trauen sich nicht mehr, es anzufassen. Neue Entwickler koennen es nicht verstehen. Jede Aenderung ist riskant.

Die Loesung: Budget fuer Refactoring einplanen. Wenn ein Feature nicht sauber passt, entweder Nein sagen oder Zeit fuer Umstrukturierung einplanen. Der "Schneller Hack jetzt, spaeter reparieren"-Ansatz wird nie spaeter repariert.

Muster 3: Abhaengigkeiten als Landminen

Moderne Software haengt von Hunderten externer Pakete ab. Jedes Paket hat eigene Abhaengigkeiten. Jede Abhaengigkeit hat ihren eigenen Update-Zyklus.

Was schiefgeht:

  • Sicherheitsluecken erfordern dringende Updates
  • Updates brechen die Kompatibilitaet mit anderen Abhaengigkeiten
  • Veraltete Pakete erhalten keine Sicherheitspatches mehr
  • Verschiedene Pakete erfordern widersprueechliche Versionen gemeinsamer Abhaengigkeiten
  • Major-Version-Updates erfordern Codeaenderungen in der gesamten Anwendung
Der Zeitablauf:

Monat 1: Alles funktioniert, Abhaengigkeiten sind aktuell. Monat 6: Einige Pakete sind veraltet, keine dringenden Probleme. Monat 12: Mehrere Pakete haben bekannte Schwachstellen, Updates erfordern kaskadierende Aenderungen, einige Pakete sind veraltet. Monat 18: Irgendetwas zu updaten ist ein mehrtaegiges Projekt mit unvorhersehbaren Ergebnissen.

Die Loesung: Regelmaessige Wartung. Abhaengigkeiten monatlich aktualisieren, nicht jaehrlich. Versionen sorgfaeltig fixieren. Unnoetige Abhaengigkeiten vermeiden. Ausgereifte, gut gewartete Pakete statt trendiger neuer waehlen.

Muster 4: Die Datenbank bekommt Zaehne

Das anfaengliche Datenbankschema ergab fuer die anfaenglichen Anforderungen Sinn. Tabellen entsprachen sauber den Konzepten. Abfragen waren einfach.

Dann aenderten sich die Anforderungen. Neue Felder wurden hinzugefuegt. Alte Felder konnten nicht entfernt werden (irgendetwas koennte davon abhaengen). Beziehungen, die klar erschienen, wurden mehrdeutig.

Haeufige Symptome:

  • Tabellen mit 50+ Spalten, die meisten selten genutzt
  • Felder namens neuer_status und tatsaechlicher_status, weil die Aenderung des Originals zu riskant war
  • Abfragen, die 8 Tabellen joinen, um einfache Fragen zu beantworten
  • Inkonsistente Daten, weil sich Validierungsregeln geaendert haben, alte Daten aber bleiben
  • Mysterioese Nullable-Felder, an deren Zweck sich niemand erinnert
Das Ergebnis: Datenbankabfragen werden zu Performance-Engpaessen. Datenintegritaetsprobleme haeufen sich. Einfache Reports erfordern komplexe Aggregationen.

Die Loesung: Datenbankaenderungen genauso sorgfaeltig behandeln wie Codeaenderungen. Migrationen schreiben, die tatsaechlich Daten migrieren, nicht nur Spalten hinzufuegen. Veraltete Daten archivieren oder bereinigen. Das Schema dokumentieren.

Muster 5: Tests, die nichts testen

Das System hat Tests. Die Tests bestehen. Das System faellt trotzdem aus.

Was tatsaechlich passiert:

  • Tests pruefen, ob Code ausgefuehrt wird, nicht ob er korrekte Ergebnisse liefert
  • Tests werden fuer Idealszenarien geschrieben, nie fuer Grenzfaelle
  • Integrationstests mocken so viel, dass sie keine Integration testen
  • Tests brechen bei jeder Codeaenderung, sodass Entwickler aufhoeren, sie auszufuehren
  • Coverage-Metriken werden manipuliert (100% Abdeckung mit bedeutungslosen Assertions)
Das Ergebnis: Falsches Vertrauen. Aenderungen werden deployt, weil Tests bestehen. Nutzer entdecken die Bugs. Das Vertrauen in die Testsuite verdampft.

Die Loesung: Verhalten testen, nicht Implementierung. Tests schreiben, die tatsaechlich aufgetretene Bugs fangen wuerden. Tests wie Produktionscode warten. Tests loeschen, die keine echten Probleme erkennen.

Muster 6: Umgebungsdrift

Development funktioniert. Staging funktioniert. Production bricht.

Warum das passiert:

  • Development laeuft auf einer anderen OS-Version
  • Staging hat weniger Speicher/CPU als Production
  • Umgebungsvariablen unterscheiden sich auf subtile Weise
  • Production hat Datenmuster, die in Testumgebungen nicht existieren
  • Caching verhaelt sich unter realer Last anders
Das Ergebnis: "Funktioniert auf meinem Rechner" wird zum Meme, weil es staendig stimmt. Das Debugging von Produktionsproblemen erfordert die Reproduktion von Umgebungen, die niemand vollstaendig versteht.

Die Loesung: Containerisieren. Dieselben Docker-Images ueber alle Umgebungen verwenden. Umgebungs-Setup automatisieren. Mit produktionsaehnlichen Datenvolumen testen.

Muster 7: Der fehlende Bus-Faktor

Eine Person versteht das System tiefgruendig. Alle anderen haben Oberflaechenwissen.

Das Risiko:

  • Diese Person wird zum Engpass fuer alle Entscheidungen
  • Wenn sie nicht verfuegbar ist, stoppt der Fortschritt
  • Wenn sie geht, geht das institutionelle Wissen mit
  • Sie akkumuliert "undokumentierte Entscheidungen", die zu Landminen werden
Das Ergebnis: Die Zukunft des Systems haengt an einem einzigen Ausfallpunkt. Und diese Person geht irgendwann -- alle tun es.

Die Loesung: Pair Programming. Code-Reviews, die tatsaechlich Wissen transferieren. Dokumentationspflichten. Cross-Training. Keine Ein-Personen-Verantwortung fuer kritische Systeme.

Was "wartbar" wirklich bedeutet

Wartbare Software ist nicht perfekte Software. Es ist Software, bei der:

1. Ein neuer Entwickler sie in Tagen versteht, nicht in Wochen. Die Struktur ist offensichtlich. Die Konventionen sind konsistent. Die Dokumentation existiert.

2. Aenderungen lokal bleiben. Die Aenderung von Feature X zerstoert nicht die Features Y und Z. Die Grenzen zwischen Komponenten sind klar.

3. Abhaengigkeiten handhabbar sind. Updates kaskadieren nicht unvorhersehbar. Es gibt einen klaren Prozess, um alles aktuell zu halten.

4. Tests echte Probleme fangen. Wenn Tests bestehen, hat das Team tatsaechliches Vertrauen. Wenn Tests fehlschlagen, weist der Fehler auf ein reales Problem hin.

5. Umgebungen reproduzierbar sind. Das Einrichten der Entwicklungsumgebung ist geskriptet. Staging entspricht Production. Deployments sind vorhersehbar.

6. Wissen verteilt ist. Mehrere Personen koennen Aenderungen vornehmen. Dokumentation erfasst Entscheidungen.

Warum das immer wieder passiert

Das Muster wiederholt sich wegen einer Anreizfehlstellung:

Waehrend der Entwicklung:

  • Geschwindigkeit wird belohnt
  • Funktionierende Features sind sichtbar
  • Dokumentation ist unsichtbar
  • Technische Schulden sind unsichtbar
  • Budget ist fix
Waehrend der Wartung:
  • Geschwindigkeit haengt von Codequalitaet ab
  • Jede Abkuerzung wird sichtbar
  • Fehlende Dokumentation blockiert Fortschritt
  • Technische Schulden fordern Bezahlung
  • Budget fuer "Aufraeuemen" ist schwer zu rechtfertigen
Die Entwickler, die das System bauen, sind oft nicht die Entwickler, die es warten. Das Unternehmen, das jetzt fuer Features bezahlt, spuert den Schmerz der Wartung nicht sofort. Alle handeln rational innerhalb ihrer Rahmenbedingungen -- und das System degradiert vorhersehbar.

Wie wir bei QPC8 entwickeln

Bei QPC8 ist Wartbarkeit nicht optional. Jedes System, das wir ausliefern, folgt denselben Prinzipien:

Dokumentation ist Teil der Lieferung. Wir betrachten ein Projekt nicht als abgeschlossen, bis die README das Setup erklaert, die Architektur dokumentiert ist und das Deployment geskriptet ist.

Wir refactoren waehrend wir bauen. Wenn sich Anforderungen mitten im Projekt aendern (das tun sie immer), strukturieren wir um, statt dranzubauen. Das kostet kurzfristig mehr. Es kostet ueber die Lebensdauer des Systems dramatisch weniger.

Abhaengigkeiten sind konservativ. Wir waehlen ausgereifte, gut gewartete Pakete. Wir meiden trendige Bibliotheken, die naechstes Jahr aufgegeben sein koennten. Wir halten die Anzahl der Abhaengigkeiten niedrig.

Tests fangen echte Bugs. Unsere Tests konzentrieren sich auf Verhalten, das zaehlt. Wir jagen keinen Coverage-Metriken hinterher -- wir jagen Vertrauen hinterher.

Kein Ein-Personen-Wissen. Unsere Systeme sind gut genug dokumentiert, dass jeder Ingenieur sie warten kann. Das ist nicht verhandelbar.

Das Ergebnis: Systeme, die ueber die Zeit gesund bleiben. Kunden, die Aenderungen vornehmen koennen, ohne auf Landminen zu stossen. Software, die ein Vermoegenswert bleibt, keine Belastung.

Die Kosten, es richtig zu machen

Wartbare Software zu bauen kostet im Voraus mehr. Vielleicht 20-30% mehr als die schnellstmoegliche Auslieferung.

Aber:

  • Wartung in Jahr 2 ist 50% guenstiger
  • Aenderungen in Jahr 3 sind 70% guenstiger
  • Das System kann sich weiterentwickeln, statt ersetzt werden zu muessen
  • Interne Teams koennen ohne externe Hilfe beitragen
  • Sie koennen den Anbieter wechseln, ohne von vorne anzufangen
Die Unternehmen, die die billigstmoegliche V1 bauen, bezahlen sie oft dreimal: einmal fuer den initialen Bau, einmal fuer Notfall-Reparaturen und einmal fuer den eventuellen Ersatz.

Die Unternehmen, die in Qualitaet investieren, bezahlen einmal und iterieren.

Fragen, die Sie Ihren Entwicklern stellen sollten

Wenn Sie Softwareentwicklung evaluieren (oder bestehende Software warten), fragen Sie:

1. Wie richte ich eine Entwicklungsumgebung ein? Wenn die Antwort mehr als 10 Minuten Erklaerung braucht, gibt es ein Problem.

2. Zeigen Sie mir die Dokumentation. Wenn es keine gibt, sind Sie von Stammesswissen abhaengig.

3. Wann haben Sie zuletzt Abhaengigkeiten aktualisiert? Wenn die Antwort "beim Launch" lautet, haben Sie eine tickende Zeitbombe.

4. Was passiert, wenn Sie vom Bus ueberfahren werden? Wenn niemand sonst das System warten kann, haben Sie einen einzigen Ausfallpunkt.

5. Wie deploye ich eine Aenderung? Wenn der Prozess nicht dokumentiert und automatisiert ist, ist jedes Deployment riskant.

Die Antworten verraten Ihnen, ob Ihre Software ein Vermoegenswert oder eine Belastung ist.

---

QPC8 baut Produktionssysteme, die auf langfristige Wartbarkeit ausgelegt sind. Unsere ausgelieferten Systeme ansehen oder Ihr Projekt konfigurieren.

Softwareentwicklungtechnische SchuldenWartbarkeitCodequalitaetArchitektur2025

Need this built?

We build production systems that implement these concepts. Get transparent pricing on your project.

Configure Your System →

Related Posts

Web Systems

Warum die meisten SaaS-Backends bei der Skalierung scheitern

Haeufige Architekturfehler, die SaaS-Produkte beim Wachstum ruinieren. So bauen Sie Backends, die 10-fachen Traffic ohne Neuschreibung bewaeltigen.

Web Systems

Guenstige Webentwicklung an der Costa del Sol — Was Sie fuer 290 EUR wirklich bekommen

Sie suchen guenstige Webentwicklung an der Costa del Sol? Hier ist genau, was 290 EUR kauft — eine echte Next.js-Seite, keine WordPress-Katastrophe.

Web Systems

Guenstigste professionelle Website in Malaga — Warum 290 EUR besser ist als kostenlos

Kostenlose Website-Builder versprechen alles. Hier ist, warum eine professionelle 290-EUR Next.js-Seite sie alle uebertrifft — und Ihrem Malaga-Geschaeft tatsaechlich beim Wachsen hilft.