Die Gesetze der Softwaretechnik
(lawsofsoftwareengineering.com)- Eine Sammlung von 56 Prinzipien und Mustern, die Softwaresysteme, Teams und Entscheidungsprozesse beeinflussen, an einem Ort gebündelt und ein breites Spektrum von Teamführung über Architektur, Qualität und Design bis hin zu Entscheidungen abdeckt
- Teambezogene Gesetze wie Conways Gesetz, Brooks’s Law und Dunbars Zahl zeigen, dass die Organisationsstruktur Systemdesign und Produktivität direkt beeinflusst
- Im Bereich Architektur werden mit Hyrum’s Law, dem CAP-Theorem, Galls Gesetz und weiteren Konzepten Einschränkungen und Prinzipien zusammengefasst, die beim Entwurf komplexer Systeme unbedingt zu berücksichtigen sind
- Qualitätsbezogene Gesetze behandeln Technical Debt, die Testing-Pyramide, Kernighan’s Law und die praktischen Schwierigkeiten bei der Aufrechterhaltung von Codequalität und beim Debugging
- Im Bereich Entscheidungsfindung werden mit dem Dunning-Kruger-Effekt, dem Sunk-Cost-Fehlschluss, dem Pareto-Prinzip und weiteren Konzepten kognitive Verzerrungen und Beurteilungsmaßstäbe abgedeckt, in die man im Entwicklungsprozess leicht gerät
Teams
1. Conways Gesetz (Conway's Law)
> Organisationen entwerfen Systeme, die ihre Kommunikationsstrukturen widerspiegeln
- Softwarearchitekturen folgen natürlicherweise der Kommunikationsstruktur der Organisation, die sie geschaffen hat
- Wenn ein Team in drei Gruppen aufgeteilt ist, neigt auch das System dazu, in drei große Module gegliedert zu sein
- Dieses Prinzip lässt sich auch umgekehrt nutzen: mit dem „Inverse Conway Maneuver“, also dem Ansatz, die Teamstruktur zuerst passend zur gewünschten Architektur umzubauen
- Bei der Einführung von Microservices ist es effektiv, Teamgrenzen und Servicegrenzen aufeinander abzustimmen
2. Brooks’s Law
> Wenn man einem verspäteten Softwareprojekt zusätzliche Arbeitskräfte hinzufügt, wird es noch später fertig
- Wenn neue Mitarbeitende dazukommen, verbringen bestehende Teammitglieder Zeit mit Einarbeitung und Abstimmung, wodurch die Gesamtproduktivität vorübergehend sinkt
- Mit wachsender Teamgröße steigt die Zahl der Kommunikationswege exponentiell (bei n Personen: n(n-1)/2)
- Frederick Brooks formulierte das Gesetz 1975 in The Mythical Man-Month auf Grundlage seiner Erfahrungen mit dem IBM-OS/360-Projekt
- Es lässt sich quantitativ mit Little’s Law (L = λ × W) erklären: Werden zusätzliche Personen hinzugefügt, steigt das WIP (Work in Progress), während der Durchsatz stagniert, sodass die Lead Time sogar zunimmt
- Die Lösung ist nicht mehr Personal, sondern Anpassung des Umfangs oder Änderung des Zeitplans
3. Dunbars Zahl (Dunbar's Number)
> Die kognitive Grenze stabil aufrechterhaltbarer Beziehungen pro Person liegt bei etwa 150
- Eine von Robin Dunbar aus der Korrelation zwischen Primatenhirngröße und sozialer Gruppengröße abgeleitete Zahl
- Dunbars soziale Hierarchie: ~5 Personen (enge Beziehungen), ~15 Personen (vertrauenswürdige Mitwirkende), ~50 Personen (enge Arbeitsbeziehungen), ~150 Personen (stabile soziale Verbindungen)
- Wenn eine Engineering-Organisation mehr als 150 Personen umfasst, stößt informelle Kommunikation an ihre Grenzen, sodass formale Hierarchien und Prozesse nötig werden
- Amazons „Two-Pizza Team“ (5–10 Personen) spiegelt wider, dass selbst innerhalb von 150 Personen effektive Zusammenarbeit in kleineren Einheiten stattfindet
4. Ringelmann-Effekt (The Ringelmann Effect)
> Je größer die Gruppe, desto geringer die individuelle Produktivität
- Mit zunehmender Gruppengröße nimmt der Beitrag jedes Einzelnen ab – ein Phänomen des „Social Loafing“
- Auch in Softwareteams verwässert bei größerer Teamgröße die individuelle Verantwortlichkeit, während die Abstimmungskosten steigen
- Erklärt, warum kleine Teams pro Person oft mehr Output liefern
5. Price’s Law
> Eine Anzahl von Personen entsprechend der Quadratwurzel der Gesamtzahl der Beteiligten leistet 50 % der gesamten Arbeit
- In einer Organisation mit 100 Personen übernehmen etwa 10 Personen die Hälfte der gesamten Arbeit
- Je größer die Organisation wird, desto stärker wächst die Abhängigkeit von einer kleinen Zahl besonders leistungsstarker Personen
- Erklärt, warum Produktivität beim Skalieren eines Teams nicht linear steigt
6. Putt’s Law
> Wer Technologie versteht, managt nicht – und wer managt, versteht Technologie nicht
- Eine satirische Zuspitzung der Kluft zwischen Managementrolle und technischer Expertise in technischen Organisationen
- Beim Entwurf technischer Führungsstrukturen sollte diese Lücke erkannt und durch Ausgleichsmechanismen abgefedert werden
7. Peter-Prinzip (Peter Principle)
> In einer Hierarchie neigt jede angestellte Person dazu, bis zu ihrer Stufe der Unfähigkeit befördert zu werden
- Das Muster, dass jemand in einer bestimmten Rolle kompetent ist, befördert wird und in der neuen Rolle unfähig wird
- Spiegelt die Realität wider, dass hervorragende Entwickler:innen nicht automatisch gute Manager:innen sind
- Daraus ergibt sich die Notwendigkeit eines Dual-Ladder-Systems, das IC-(Individual Contributor-) und Management-Laufbahnen trennt
8. Bus Factor
> Die minimale Zahl von Teammitgliedern, deren Ausfall ein Projekt in ernsthafte Gefahr bringen würde
- Ein Bus Factor von 1 bedeutet, dass ein Single Point of Failure existiert
- Es ist wichtig, den Bus Factor durch Wissensaustausch, Pair Programming und Dokumentation zu erhöhen
- Code Reviews und Cross-Training sind praktische Wege, den Bus Factor zu verbessern
9. Dilbert-Prinzip (Dilbert Principle)
> Unternehmen neigen dazu, inkompetente Mitarbeitende in Managementpositionen zu befördern, um den Schaden zu begrenzen
- Eine von Scott Adams vorgeschlagene satirische Beobachtung und eine Variante des Peter-Prinzips
- Ein paradoxes Organisationsphänomen, bei dem Managementpositionen als die Stellen gelten, an denen im operativen Geschäft der geringste Schaden entsteht
Planung
10. Vorzeitige Optimierung / Knuths Optimierungsprinzip (Premature Optimization)
> Vorzeitige Optimierung ist die Wurzel allen Übels
- Donald Knuth formulierte 1974: „In etwa 97 % der Fälle sollte man kleine Effizienzgewinne ignorieren“
- Da etwa 20 % des Codes 80 % der Laufzeit verursachen, ist es Verschwendung, die übrigen 80 % des Codes zu optimieren
- Die richtige Reihenfolge: Zuerst zum Laufen bringen → dann korrekt machen → und nur wenn nötig schneller machen
- Optimierter Code erhöht die Komplexität; daher sollte erst per Profiling der tatsächliche Engpass ermittelt und dann optimiert werden
11. Parkinsons Gesetz (Parkinson's Law)
> Arbeit dehnt sich so aus, dass sie die dafür verfügbare Zeit vollständig ausfüllt
- Wenn die Deadline 2 Wochen beträgt, wächst die Arbeit auf 2 Wochen; bei 4 Wochen auf 4 Wochen
- Erklärt, warum in Softwareprojekten kurze und klare Meilensteine wichtig sind
- Sprint-basiertes Agile ist eine praktische Antwort auf dieses Gesetz
12. 90-90-Regel (The Ninety-Ninety Rule)
> Die ersten 90 % des Codes beanspruchen 90 % der Entwicklungszeit, und die restlichen 10 % nochmals weitere 90 % der Zeit
- Warnt davor, dass die letzten 10 % eines Softwareprojekts – Edge Cases, Polishing, Bugfixes – viel länger dauern als erwartet
- „Fast fertig“ kann in Wirklichkeit erst die Hälfte des gesamten Zeitplans bedeuten
13. Hofstadters Gesetz (Hofstadter's Law)
> Es dauert immer länger als erwartet, selbst wenn man Hofstadters Gesetz berücksichtigt
- Ein Gesetz mit rekursiver Selbstreferenz, das die grundsätzliche Schwierigkeit von Aufwandsschätzungen in der Softwareentwicklung ausdrückt
- Die Realität, dass selbst mit zusätzlichem Puffer Termine weiterhin überschritten werden
- Eingeführt von Douglas Hofstadter 1979 in Gödel, Escher, Bach
14. Goodharts Gesetz (Goodhart's Law)
> Sobald eine Messgröße zum Ziel wird, ist sie keine gute Messgröße mehr
- Ein typisches Beispiel ist, wenn Code Coverage zum KPI gemacht wird und dadurch bedeutungslose Tests in großer Zahl entstehen
- Wenn Produktivität über Lines of Code (LOC) gemessen wird, entsteht unnötig aufgeblähter Code
- Statt Metriken zu optimieren, sollte man sich auf das Erreichen des eigentlichen Werts konzentrieren
15. Gilbs Gesetz (Gilb's Law)
> Wenn etwas quantifiziert werden muss, ist es besser, es irgendwie zu messen, als es gar nicht zu messen
- Selbst wenn perfekte Messung unmöglich ist, ist eine ungefähre Messung immer nützlicher als gar keine Messung
- Gilt auch für schwer quantifizierbare Größen wie Softwarequalität oder Nutzerzufriedenheit
Architektur
16. Hyrum’s Law
> Wenn es genug Nutzer einer API gibt, wird sich irgendjemand auf jedes beobachtbare Verhalten des Systems verlassen
- Nicht nur offizielle API-Spezifikationen, sondern auch inoffizielle Verhaltensweisen wie Timing, Format von Fehlermeldungen und Sortierreihenfolgen werden zu Abhängigkeiten
- Ein Beispiel dafür ist, dass Microsoft Windows ältere Verhaltensweisen beibehielt, um die Kompatibilität mit Drittanbieter-Apps zu sichern, die von nicht dokumentiertem Verhalten und Bugs aus der Vergangenheit abhingen
- Beobachtet von Googles Hyrum Wright um 2011–2012 bei Erfahrungen mit Änderungen interner Google-Bibliotheken
- Sein Kollege Titus Winters gab dem den Namen "Hyrum's Law" (Software Engineering at Google)
- Der tatsächliche Vertrag ist nicht die offizielle API, sondern das gesamte real beobachtbare Verhalten
17. Galls Gesetz (Gall's Law)
> Ein funktionierendes komplexes System ist zwangsläufig aus einem funktionierenden einfachen System hervorgegangen
- Wenn man von Anfang an ein komplexes System entwirft, gibt es zu viele ungetestete Unbekannte, wodurch die Wahrscheinlichkeit des Scheiterns steigt
- Die theoretische Grundlage für den MVP(Minimum Viable Product)-Ansatz
- Beispiel: Facebook begann 2004 als einfaches Profilsystem für Harvard-Studierende und wurde schrittweise erweitert
- Auch bei der Umstellung auf Microservices ist es vorteilhaft, mit einem Monolithen zu beginnen und ihn schrittweise aufzuspalten
- Von John Gall 1975 in seinem Buch Systemantics vorgestellt (ein Kultklassiker, der erst nach Ablehnung durch 30 Verlage erschien)
18. Das Gesetz der leaky abstractions (The Law of Leaky Abstractions)
> Jede nicht triviale (non-trivial) Abstraktion leckt in gewissem Maß
- Ein typisches Beispiel ist, dass ein ORM SQL verbirgt, man bei Performance-Problemen aber letztlich doch die erzeugten Queries prüfen muss
- Auch Garbage Collection in Java/Python ist eine Abstraktion, doch internes Verhalten wie GC-Pausen beeinflusst die Performance
- Die Lehre ist nicht, dass Abstraktionen an sich schlecht sind, sondern dass man auf den Fall vorbereitet sein muss, dass die Abstraktion bricht
- Von Joel Spolsky 2002 in einem Blogpost anhand von Beispielen wie TCP und virtuellem Speicher vorgestellt
- Inhaltlich anschlussfähig an George Box’ Satz: "Alle Modelle sind falsch, aber manche sind nützlich"
19. Teslers Gesetz / Gesetz der Erhaltung von Komplexität (Tesler's Law)
> Jede Applikation besitzt eine inhärente Komplexität, die sich nicht entfernen lässt; sie kann nur verlagert, nicht beseitigt werden
- Die Kernfrage lautet: Wer trägt die Komplexität? (Nutzer vs. System)
- Calendly absorbiert die Komplexität der Terminabstimmung im System, während E-Mail-Threads sie auf die Nutzer abwälzen
- Gutes Design verlagert Komplexität aus der User Experience ins Innere des Systems
- Von Larry Tesler in den 1980er-Jahren während der Arbeit an Apple Lisa und frühen GUIs formuliert
20. CAP-Theorem (CAP Theorem)
> Verteilte Systeme können von Konsistenz (C), Verfügbarkeit (A) und Partitionstoleranz (P) nur zwei garantieren
- Netzwerkpartitionen sind in der Realität unvermeidlich, daher lautet die praktische Entscheidung Konsistenz vs. Verfügbarkeit
- CP-Systeme (z. B. MongoDB): Blockieren bei einer Partition Schreibvorgänge, um die Synchronisation aller Replikate aufrechtzuerhalten
- AP-Systeme (z. B. Cassandra, DNS): Beantworten Anfragen auch während einer Partition weiter und erlauben vorübergehende Inkonsistenzen zwischen Replikaten
- 2000 von Eric Brewer im Kontext von Web Services vorgeschlagen, 2002 von Gilbert & Lynch formal bewiesen
21. Second-System-Effekt (Second-System Effect)
> Auf ein kleines und erfolgreiches System folgt oft ein überentwickeltes, aufgeblähtes Nachfolgesystem
- Nach dem Erfolg des ersten Systems entsteht oft das Muster, beim zweiten System alle Ideen hineinzupacken
- Die Hauptursachen sind Feature Creep und übermäßige Verallgemeinerung (over-generalization)
- Von Frederick Brooks in The Mythical Man-Month identifiziert
22. Trugschlüsse des Distributed Computing (Fallacies of Distributed Computing)
> Acht falsche Annahmen, die Menschen beim ersten Entwurf verteilter Systeme häufig treffen
- Die 8 Trugschlüsse: (1) Das Netzwerk ist zuverlässig, (2) die Latenz ist 0, (3) die Bandbreite ist unendlich, (4) das Netzwerk ist sicher, (5) die Topologie ändert sich nicht, (6) es gibt nur einen Administrator, (7) die Transportkosten sind 0, (8) das Netzwerk ist homogen
- Wenn man auf Basis dieser Annahmen entwirft, entstehen in Produktion unerwartete Ausfälle und Performance-Probleme
23. Gesetz der unbeabsichtigten Folgen (Law of Unintended Consequences)
> Wenn man ein komplexes System verändert, muss man mit unbeabsichtigten Folgen rechnen
- Verändert man eine Komponente eines Systems, treten Nebenwirkungen an nicht vorhergesehenen Stellen auf
- Ein Prinzip, das die Notwendigkeit von Chaos Engineering und umfassendem Testing stützt
24. Zawinskis Gesetz (Zawinski's Law)
> Jedes Programm versucht sich so lange zu erweitern, bis es E-Mails lesen kann
- Eine satirische Beobachtung zur Funktionsaufblähung (feature bloat): Wenn Software erfolgreich ist, will man immer mehr Funktionen hinzufügen
- Beobachtet von Jamie Zawinski (früher Netscape-Entwickler)
- Eine Warnung vor der Tendenz, dass einfache Werkzeuge mit der Zeit zu universellen Plattformen werden wollen
Qualität (Quality)
25. Boy-Scout-Regel (The Boy Scout Rule)
> Hinterlasse den Code in einem besseren Zustand, als du ihn vorgefunden hast
- Entscheidend ist nicht ein großes Refactoring, sondern kontinuierliche und schrittweise Verbesserung
- Dinge wie verwirrende Funktionsnamen korrigieren, doppelten Code entfernen oder fehlende Tests ergänzen — also jedes Mal kleine Verbesserungen umsetzen
- Von Robert C. Martin (Uncle Bob) in Clean Code (2008) auf die Softwareentwicklung angewandt
- Das Prinzip der Google-Ingenieure "If you touch it, you own it" — wer Code ändert, übernimmt auch Verantwortung für dessen Qualität
- Wer diese Regel befolgt, verhindert den Broken-Windows-Effekt und beugt der Anhäufung technischer Schulden vor
26. Murphys Gesetz (Murphy's Law)
> Alles, was schiefgehen kann, wird auch schiefgehen
- Grundlage für defensives Programmieren, Exception Handling und ausfallsichere Architektur
- In der Softwareentwicklung sollte man mit der Haltung arbeiten: "Jeder Fehler, der auftreten kann, wird irgendwann auftreten" — und entsprechend Error Handling und Fallbacks entwerfen
27. Postels Gesetz / Robustheitsprinzip (Postel's Law)
> Sei konservativ in dem, was du tust, und großzügig in dem, was du von anderen annimmst
- Bei der API-Gestaltung gilt das Prinzip, dass Outputs die Spezifikation strikt einhalten sollten, Inputs jedoch flexibel verschiedene Formate akzeptieren
- Das von Jon Postel beim Entwurf der TCP/IP-Protokolle formulierte Robustheitsprinzip (Robustness Principle)
- Eine praktische Leitlinie zur Verbesserung der Interoperabilität zwischen Systemen
28. Broken-Windows-Theorie (Broken Windows Theory)
> Schlechtes Design, falsche Entscheidungen und minderwertigen Code nicht unbeaufsichtigt lassen
- Wenn ein "kaputtes Fenster" (schlechter Code) liegen bleibt, führt das zu weiterem Qualitätsverfall
- Wenn sich TODO-Kommentare, toter Code und ungelöste Warnungen in einer Codebasis ansammeln, wird auch neuer Code tendenziell auf niedrigerem Niveau geschrieben
- Wichtig ist eine Kultur, in der auch kleine Probleme sofort behoben werden
29. Technische Schulden (Technical Debt)
> Alle Faktoren, die die Geschwindigkeit der Softwareentwicklung verlangsamen
- Von Ward Cunningham 1992 auf der OOPSLA erstmals als Finanzmetapher verwendet: Wer Abkürzungen im Code nimmt, leiht sich Zeit aus der Zukunft
- Kapital (Kosten der Behebung) + Zinsen (dauerhafter Produktivitätsverlust durch unordentlichen Code)
- Bewusste technische Schulden sind manchmal rational, etwa für Time-to-Market oder Prototyping, aber ein Tilgungsplan ist unverzichtbar
- Ein typisches Beispiel ist das Weglassen automatisierter Tests: Der Release gelingt zwar, aber bei späteren Änderungen treten immer wieder unerwartete Bugs auf
- Lösungen: Refactoring, fehlende Tests ergänzen, Design verbessern
30. Linus' Gesetz (Linus's Law)
> Bei genügend vielen Prüfern lassen sich alle Bugs leicht finden
- Ein Grundprinzip der Open-Source-Entwicklung: Wenn viele Augen den Code prüfen, werden Bugs zu trivialen Problemen
- Von Eric Raymond in The Cathedral and the Bazaar nach Linus Torvalds benannt
- Unterstreicht die Bedeutung einer Kultur von Code Reviews
31. Kernighans Gesetz (Kernighan's Law)
> Debugging ist doppelt so schwer wie das ursprüngliche Schreiben des Codes
- Daher gilt: Wenn man Code so clever wie möglich schreibt, ist man beim Debuggen nicht mehr clever genug dafür
- Das ist der Grund, warum man einfachen, gut lesbaren Code schreiben sollte
- Vorgestellt von Brian Kernighan in The Elements of Programming Style
32. Testpyramide (Testing Pyramid)
> Ein Projekt sollte viele schnelle Unit-Tests, weniger Integrationstests und nur wenige UI-Tests besitzen
- Unit-Tests (unten): schnell und kostengünstig, daher am häufigsten
- Integrationstests (Mitte): prüfen die Interaktion zwischen Komponenten
- UI-/E2E-Tests (oben): langsam und fragil, daher auf ein Minimum reduzieren
- Ein Teststrategie-Modell, das Mike Cohn in Succeeding with Agile vorgestellt hat
33. Pestizid-Paradoxon (Pesticide Paradox)
> Wenn dieselben Tests wiederholt ausgeführt werden, nimmt ihre Wirksamkeit mit der Zeit ab
- Da bestehende Tests alle Fehler finden, die sie finden können, müssen kontinuierlich neue Testfälle hinzugefügt werden
- Es ist unerlässlich, die Test-Suite regelmäßig zu prüfen und zu aktualisieren
34. Lehmans Gesetze der Softwareevolution (Lehman's Laws of Software Evolution)
> Software, die die reale Welt abbildet, muss sich zwangsläufig weiterentwickeln, und diese Entwicklung unterliegt vorhersehbaren Grenzen
- E-Type-Software (die die reale Welt abbildet) muss fortlaufend verändert werden, um nutzbar zu bleiben
- Mit jeder Änderung nimmt die Komplexität zu; wird sie nicht aktiv gemanagt, leidet die Qualität
35. Sturgeons Gesetz (Sturgeon's Law)
> 90 % von allem sind wertlos
- Von Theodore Sturgeon als Reaktion auf Kritik an der Science-Fiction-Literatur formuliert
- Gilt auch für Software: Von Code, Tools und Frameworks ist nur ein kleiner Teil wirklich herausragend
- Wichtig ist, hohe Qualitätsmaßstäbe zu halten und sich auf die wertvollen 10 % zu konzentrieren
Skalierung (Scale)
36. Amdahls Gesetz (Amdahl's Law)
> Die durch Parallelisierung erzielte Beschleunigung ist durch den Anteil der nicht parallelisierbaren Arbeit begrenzt
- Wenn 5 % eines Programms sequentiell sind, beträgt die theoretische maximale Beschleunigung selbst mit beliebig vielen Prozessoren nur das 20-Fache
- Es ist oft wirksamer, die Grenzen der Parallelisierung zu erkennen und sequentielle Engpässe zu reduzieren
- 1967 von Gene Amdahl formuliert
37. Gustafsons Gesetz (Gustafson's Law)
> Durch Vergrößerung des Problemumfangs lässt sich bei paralleler Verarbeitung eine erhebliche Beschleunigung erzielen
- Eine ergänzende Perspektive zu Amdahls Gesetz: Bei skalierbaren statt festen Problemen bringt das Hinzufügen von Prozessoren deutliche Vorteile
- Bei Big-Data-Verarbeitung, wissenschaftlichen Simulationen usw. lassen sich mit mehr Ressourcen größere Probleme lösen
38. Metcalfes Gesetz (Metcalfe's Law)
> Der Wert eines Netzwerks ist proportional zum Quadrat der Anzahl seiner Nutzer
- Bei 10 Nutzern beträgt der Wert 100 Einheiten, bei 100 Nutzern 10.000 Einheiten
- Die theoretische Grundlage für Netzwerkeffekte bei sozialen Netzwerken, Messengern, Marktplätzen usw.
- Von Robert Metcalfe formuliert, um den Wert der Ethernet-Technologie zu erklären
Entwurf (Design)
39. DRY-Prinzip (Don't Repeat Yourself)
> Jedes Wissen sollte nur eine einzige, eindeutige und maßgebliche Darstellung haben
- Gemeint ist nicht nur Codeduplizierung, sondern auch Duplizierung von Wissen, Logik und Daten
- Duplikate führen dazu, dass bei Änderungen mehrere Stellen gleichzeitig angepasst werden müssen, und sind damit eine Ursache für Fehler und Inkonsistenzen
- Von Andy Hunt und Dave Thomas in The Pragmatic Programmer geprägt
40. KISS-Prinzip (Keep It Simple, Stupid)
> Entwürfe und Systeme sollten so einfach wie möglich sein
- Komplexität erhöht die Kosten für Verständnis, Wartung und Debugging
- Einfache Lösungen sind in den meisten Fällen wirksamer und weniger fehleranfällig
- Geht auf ein in den 1960er Jahren von der US Navy formuliertes Entwurfsprinzip zurück
41. SOLID-Prinzipien (SOLID Principles)
> Fünf zentrale Leitlinien zur Verbesserung des Softwaredesigns
- S — Single-Responsibility-Prinzip: Eine Klasse sollte nur aus einem einzigen Grund geändert werden
- O — Open-Closed-Prinzip: offen für Erweiterung, geschlossen für Änderung
- L — Liskov-Substitutionsprinzip: Untertypen sollten Obertypen ersetzen können
- I — Interface-Segregation-Prinzip: Clients sollten nicht von Interfaces abhängen, die sie nicht verwenden
- D — Dependency-Inversion-Prinzip: Höhere Module sollten nicht von niedrigeren abhängen, sondern von Abstraktionen
- Von Robert C. Martin formuliert; das Akronym SOLID wurde von Michael Feathers geprägt
42. Gesetz von Demeter (Law of Demeter)
> Objekte sollten nur mit ihren direkten Freunden interagieren und den direkten Kontakt mit fremden Objekten vermeiden
- Das Prinzip besagt, dass verkettete Aufrufe wie
a.getB().getC().doSomething()vermieden werden sollten - Senkt die Kopplung und stärkt die Kapselung, wodurch der Änderungsradius kleiner wird
- Auch als „Prinzip des geringsten Wissens“ bekannt
43. Prinzip der geringsten Überraschung (Principle of Least Astonishment)
> Software und Interfaces sollten so funktionieren, dass sie Nutzer und andere Entwickler möglichst wenig überraschen
- Funktionen, API und UI sollten bei Namen und Konventionen vorhersehbares Verhalten zeigen
- Wenn eine
delete()-Funktion in Wirklichkeit nur archiviert, erzeugt das Überraschung → ein Designfehler - Nicht intuitive Verhaltensweisen führen zu Bugs und Bedienfehlern
44. YAGNI (You Aren't Gonna Need It)
> Füge keine Funktionen hinzu, bevor sie wirklich gebraucht werden
- Ein Kernprinzip von Extreme Programming (XP), Ende der 1990er Jahre von Ron Jeffries formuliert
- Code zu schreiben, weil man ihn „vielleicht später brauchen könnte“, führt zu Overengineering und höherem Wartungsaufwand
- Um YAGNI praktisch umzusetzen, braucht es Vertrauen ins Refactoring (gute Testabdeckung, CI)
- Wenn aktuell nur JSON-Export benötigt wird, implementiert man nur JSON; XML/YAML usw. werden erst bei Bedarf ergänzt
Entscheidungen (Decisions)
45. Dunning-Kruger-Effekt (Dunning-Kruger Effect)
> Je weniger man über etwas weiß, desto selbstsicherer ist man oft
- Das zeigt sich etwa darin, dass Junior-Entwickler die Schwierigkeit komplexer Systeme unterschätzen, während Experten mit ihrem eigenen Wissen oft bescheidener umgehen
- Durch Code-Reviews, Mentoring und kontinuierliches Lernen lässt sich die Genauigkeit der Selbsteinschätzung verbessern
46. Hanlons Rasiermesser (Hanlon's Razor)
> Schreibe nichts böser Absicht zu, was sich hinreichend durch Dummheit oder Unachtsamkeit erklären lässt
- Bevor man schlechten Code oder falsche Entscheidungen von Kollegen als absichtliche Sabotage deutet, sollte man zuerst Unwissen, Fehler oder Zeitmangel in Betracht ziehen
- Eine Grundlage für Vertrauen im Team und konstruktive Kommunikation
47. Ockhams Rasiermesser (Occam's Razor)
> Die einfachste Erklärung ist oft die zutreffendste
- Beim Debugging sollte man vor komplexen Ursachen zuerst die einfachste Möglichkeit prüfen
- Auch im Architekturdesign sollte man einfache Lösungen priorisieren, bevor man unnötige Abstraktionsschichten einführt
48. Sunk-Cost-Fallacy
> Das Phänomen, an einer verlustreichen Entscheidung festzuhalten, nur weil bereits Zeit oder Energie investiert wurde
- Die psychologische Tendenz, eine sechs Monate lang entwickelte Funktion nicht aufgeben zu können, weil bereits so viel Zeit investiert wurde, obwohl sie in die falsche Richtung geht
- Richtige Entscheidungen sollten sich nicht an vergangenen Investitionen, sondern am zukünftigen Wert orientieren
49. Die Landkarte ist nicht das Territorium (The Map Is Not the Territory)
> Eine Darstellung der Realität (ein Modell) ist nicht identisch mit der Realität selbst
- UML-Diagramme, Architekturdokumente und Datenmodelle sind nur Annäherungen an die Realität
- Man sollte Modellen nicht blind vertrauen, sondern das Verhalten des realen Systems beobachten und die Modelle entsprechend aktualisieren
50. Bestätigungsfehler (Confirmation Bias)
> Die Tendenz, Informationen zu bevorzugen, die bestehende Überzeugungen oder Ideen stützen
- Eine Falle, bei der man nur Informationen sammelt, die den eigenen gewählten Tech-Stack oder eine Designentscheidung bestätigen
- Aktiv nach Gegenbelegen zu suchen und verschiedene Perspektiven zu akzeptieren, ist der Schlüssel zu ausgewogenen Entscheidungen
51. Hype Cycle und Amaras Gesetz (The Hype Cycle & Amara's Law)
Die kurzfristigen Effekte von Technologie werden tendenziell überschätzt, ihre langfristigen Auswirkungen dagegen unterschätzt.
- Gartners Hype Cycle: technologischer Auslöser → Gipfel der überzogenen Erwartungen → Tal der Enttäuschung → Pfad der Erleuchtung → Plateau der Produktivität
- Bei der Einführung neuer Technologien (Blockchain, AI usw.) sollte man sich nicht von kurzfristiger Überhitzung mitreißen lassen, sondern die langfristige Praxistauglichkeit bewerten.
52. Lindy-Effekt (The Lindy Effect)
Je länger etwas genutzt wurde, desto wahrscheinlicher ist es, dass es auch künftig weiter genutzt wird.
- Technologien, die seit Jahrzehnten verwendet werden, wie UNIX, SQL oder die Programmiersprache C, haben eine hohe Wahrscheinlichkeit, auch in Zukunft lange zu bestehen.
- Eine theoretische Grundlage dafür, bei der Auswahl eher auf bewährte Technologien als auf neue Frameworks zu setzen.
- Von Nassim Nicholas Taleb in Antifragile popularisiert.
53. Denken in ersten Prinzipien (First Principles Thinking)
Eine Denkweise, bei der komplexe Probleme in ihre grundlegendsten Bausteine zerlegt und von dort aus neu aufgebaut werden.
- Bestehende Konventionen und Annahmen werden entfernt, und Lösungen werden von grundlegenden Wahrheiten ausgehend entwickelt.
- Bekannt durch Elon Musks Anwendung zur Senkung der Raketenkosten bei SpaceX.
- Bei der Entwicklung komplexer Systeme sollte man sich vor der Denkweise hüten: "Das macht man eben schon immer so."
54. Umkehrdenken (Inversion)
Eine Methode zur Problemlösung, bei der man das gegenteilige Ergebnis annimmt und rückwärts schlussfolgert.
- Statt „Wie werden wir erfolgreich?“ zunächst „Wie scheitern wir?“ denken, um Risikofaktoren zu identifizieren.
- Eine theoretische Grundlage für Failure Mode Analysis und Pre-mortems.
- Ein Mental Model, das Charlie Munger häufig verwendet.
55. Pareto-Prinzip / 80/20-Regel (Pareto Principle)
80 % der Probleme entstehen aus 20 % der Ursachen.
- 80 % aller Bugs konzentrieren sich tendenziell auf 20 % des Codes.
- Ressourcen auf die wirkungsvollsten 20 % zu konzentrieren, ist eine effiziente Strategie der Ressourcenallokation.
- Abgeleitet von einem Prinzip, das Vilfredo Pareto bei der Verteilung des Landbesitzes in Italien beobachtete.
56. Cunninghams Gesetz (Cunningham's Law)
Der beste Weg, im Internet eine richtige Antwort zu bekommen, ist nicht, eine Frage zu stellen, sondern eine falsche Antwort zu posten.
- Menschen beteiligen sich aktiver daran, Fehlinformationen zu korrigieren, als Fragen zu beantworten.
- Das Gesetz ist nach Ward Cunningham (dem Erfinder des Wiki) benannt, tatsächlich wurde dieser Name jedoch von Steven McGeady geprägt.
- Eine Erkenntnis, die sich in Open-Source-Communities für Dokumentation und Wissensaustausch nutzen lässt.
2 Kommentare
Wenn man Vibe Coding betreibt, fühlt es sich zunächst gut an, aber am Ende fällt es wohl auf einen selbst zurück...
Hacker-News-Kommentare
Ich hasse besonders den Spruch "frühe Optimierung ist die Wurzel allen Übels". Dieser Satz stammt aus dem Kontext von 1974 und beruht auf anderen Annahmen als heute. Damals war Optimierung näher an Assembler und dem Zählen von CPU-Zyklen, heute ist Performance vor allem eine Frage der Architekturentscheidungen und muss daher von Anfang an mitgedacht werden. Der Rat, mit Profiling zufällige Performance-Bugs wie versehentliches O(n²) aufzuspüren, ist weiterhin sinnvoll, aber sobald die Kosten von Abstraktionen zum Flaschenhals werden, endet man oft damit, nur noch Cache und Parallelität draufzupacken und ein komplexeres wie auch langsameres System zu bauen. Heute halte ich späte Optimierung für genauso schlimm wie frühe Optimierung, vielleicht sogar für schlimmer
ConcurrentHashMap, weil es später vielleicht in einen Multithreading-Kontext gehen könnte, und in den meisten Situationen ist der Performance-Unterschied gering. Trotzdem werden PRs mit der Begründung blockiert, "HashMap ist schneller", und dann entstehen endlose Debatten. Stattdessen sollte man sich lieber auf Dinge konzentrieren, die spürbare Unterschiede machen, wie 40 blockierende PostgreSQL-Aufrufe oder unnötige Web-Requests. Frühe Optimierung auf Algorithmus-Ebene halte ich dagegen durchaus für sinnvollIch finde es schade, dass Curly's Law fehlt. Eine Variable sollte nur eine Bedeutung haben und nicht je nach Situation Werte aus unterschiedlichen Domänen enthalten oder zwei Rollen gleichzeitig erfüllen. Die Metapher vom "Bodenwachs und zugleich Dessert-Topping" passt da perfekt
Wenn man solche Software-"Gesetze" an einer Stelle sammelt, wirken sie auf mich oft so innerlich widersprüchlich, dass man sich am Ende einfach den Satz aussucht, der die eigene Position stützt. Die wirklich schwierige Fähigkeit ist zu wissen, wann man welches Gesetz brechen sollte und warum
Als Scherz zur Ausgabe 2026 der Software-Engineering-Gesetze würde ich sagen, dass alle Websites mit Claude Opus vibe-coded werden. Das Ergebnis wäre dann ein cremiger Hintergrundton, der an Anthropic erinnert, übertrieben gemischte Fonts und Strichstärken, als hätte gerade jemand sein erstes Typografie-Tutorial gesehen, überall Karten-UI und ständig wiederkehrende Muster wie eine abgerundete farbige Umrandung nur auf einer Seite der Karte
Ich finde, Boyd's Law of Iteration sollte ebenfalls dabei sein. Die Aussage ist, dass beim Umgang mit Komplexität schnelle Iteration oft bessere Ergebnisse liefert als tiefgehende Analyse, und noch beeindruckender wird das, wenn man bedenkt, dass Boyd auch der Urheber der OODA loop war
Ich finde, unter den gelöschten Kommentaren gab es das beste Meta-Gesetz zu diesem Beitrag. Es lautete sinngemäß: "Alle Gesetze des Software Engineering werden sofort missverstanden und unkritisch so angewendet, dass der ursprüngliche Autor entsetzt wäre." Wenn man sieht, wie LLMs handeln, sobald der zentrale Kontext fehlt, versteht man noch besser, warum das so ist. Es gibt eben Grenzen dafür, jahrzehntelange Weisheit und Erfahrung in einen Einzeiler zu pressen
Wenn man schon eine ganze "Liste von Gesetzen des Software Engineering" vibe-codet, würde ich gern fragen, gegen welches Gesetz es verstößt, dass man nicht einfach stattdessen eine Wikipedia-Seite erstellt hat
Ich fände es gut, wenn so etwas so sehr zur Allgemeinbildung gehörte, dass es sogar eine Einstellungsvoraussetzung wäre. Es wirkt auf mich wie Wissen, das wirklich alle kennen sollten
Auch wenn es kein speziell auf Software bezogenes Gesetz ist, lehre ich Chesterton's Fence Praktikanten und Berufseinsteigern meist als Erstes
Ich finde, Teslers Gesetz der Komplexitätserhaltung vermittelt schon im Wortlaut sofort Einsicht. Jede Anwendung hat eine inhärente Komplexität, die man nicht entfernen, sondern nur verschieben kann. In der Erklärung schrumpft das für mich dann aber oft auf den banalen Rat zusammen, den Nutzer weniger zu quälen. Nutzer müssen am Ende ein gewisses Maß an nötiger Komplexität ohnehin tragen, und wenn man blind alles reduziert, bekommt man leicht ein unflexibles Spielzeug. Deshalb finde ich es nützlicher, sich beim Refactoring daran zu erinnern, dass das Vereinfachen eines Teils einen anderen Teil komplizierter machen kann