124 Punkte von GN⁺ 8 일 전 | 2 Kommentare | Auf WhatsApp teilen
  • 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

 
choam2426 2 일 전

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...

 
GN⁺ 8 일 전
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

    • Ich denke, das ist einer der am häufigsten missverstandenen Sätze in der Programmierung. Wenn man Donald Knuths Originaltext direkt liest, ist die Kernaussage: Man sollte keine Energie in unnötige Performance-Verbesserungen stecken, ohne überhaupt gemessen zu haben, außer in den 10% der Fälle, in denen Performance zentral ist. Trotzdem wird das oft als seltsames Dogma verstanden, man solle "gar nichts messen"
    • Was ich für wirklich schlechte frühe Optimierung halte, ist die Fixierung auf winzige Unterschiede, die gar nicht wichtig sind. In Java verwende ich zum Beispiel oft 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 sinnvoll
    • Ich sage scherzhaft, dass ich statt "früher Optimierung" nur reife Optimierung mache. Bevor man Frameworks übereinanderstapelt, zuerst über Nutzungsweise, Datenzugriffsmuster und Performance-Anforderungen nachzudenken, ist ein sehr reifer Ansatz. Die meisten müssen nicht bis zum Zyklenzählen gehen, aber Fragen wie Bulk Load oder Einzelverarbeitung sowie ob Nebenläufigkeit oder Verteilung berücksichtigt werden müssen, machen früh einen großen Unterschied. Das Lager, das meint, Performance könne man später bedenken, läuft bei späteren Verbesserungen oft gegen Wände
    • Ich habe letztes Jahr sechs Monate damit verbracht, eine Abstraktionsschicht zu entfernen, die pro Request 40 ms extra gekostet hat. Mit Profiling habe ich den Hot Path gefunden, aber ohne Rewrite war das Problem nicht zu lösen. Die Fraktion "optimieren wir später" sagt meist nicht dazu, dass dieses Später in Wirklichkeit nie kommen könnte
    • Ich denke, mit modernen Tools lässt sich skalierbares Design relativ leicht bauen. Deshalb verstehe ich frühe Optimierung als das unnötige Feilen an Teilen, die bereits gut genug sind, nicht als Freibrief, von Anfang an chaotischen Code zu schreiben
  • Ich 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

    • Ich würde scherzhaft sagen, dass diese Metapher vom "Bodenwachs und Dessert-Topping" vielleicht doch kein ganz universelles Gesetz ist. Aus meiner Erfahrung mit Reinigungsarbeiten in der Nähe von Restaurants glaube ich, dass es genug Leute gäbe, die Bodenwachs wie ein Topping probieren würden, wenn man ihnen sagt, dass es sie betrunken macht
    • Ich kannte dieses Prinzip nicht unter diesem Namen, habe es aber praktisch gelernt. Wenn es zum Beispiel eine Regel gibt, dass y zu 0 wird, wenn x nicht 0 ist, dann sollte man nicht über y indirekt ableiten, ob x 0 ist. Und noch schlimmer: Man sollte y nicht einfach für einen anderen Zweck wiederverwenden, nur weil es gerade frei ist
    • Mich erinnert das daran, dass Shellac tatsächlich sowohl Bodenpolitur als auch Lebensmittelzusatzstoff war. Heute gibt es bessere Alternativen, aber früher wurde es besonders bei Süßigkeiten verwendet, und soweit ich weiß, wird es auch heute noch als Klebstoff für Holzblasinstrumente genutzt
    • Ich mochte absl::StatusOr bei Google ziemlich gern
    • Ich nenne so etwas normalerweise POSIWID
  • 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

    • Ich halte den Konflikt zwischen Postel's Law und Hyrum's Law für ein typisches Beispiel. Wenn man Eingaben großzügig akzeptiert, wird sich irgendjemand auf jedes beobachtbare Verhalten einer API verlassen, und in dem Moment, in dem man später strenger wird, ist es ein Breaking Change, auch wenn es nie dokumentiert war. Mein Fazit daraus ist: An internen Grenzen, die ich kontrolliere, bin ich strikt, und nur an externen Grenzen, wo ich Client-Upgrades nicht erzwingen kann, bin ich großzügiger. In der Praxis ist aber genau diese Grenze am schwersten sauber zu ziehen
    • DRY ist für mich oft ein Paradebeispiel für solche Widersprüche. Ich habe besonders oft gesehen, dass man zwei ähnliche Funktionen vermeiden will und dafür die konzeptionelle Komplexität bis zum Himmel treibt
    • Als SWE mit ziemlich vielen Jahren Berufserfahrung ziehe ich bis heute enormen Nutzen aus KISS und YAGNI. Vieles in der Softwareentwicklung wirkt auf mich wie Überengineering, und ehrlich gesagt auch diese Seite hier. In anderen Ingenieurdisziplinen sind Material- und Personalkosten sichtbar genug, dass man sich solche Exzesse nicht lange leisten kann
    • Ich hatte bei Amazons Leadership Principles ein ähnliches Gefühl. Im Großen und Ganzen sind es plausible Leitlinien, aber in echten Debatten wurde es oft zu einem Kampf darum, welches Prinzip sich am überzeugendsten als Waffe an die eigene Position hängen ließ. Ich denke aber auch, dass das nicht nur schlecht sein muss
    • Statt formeller IT-Gesetzeskriege mag ich Alternativen wie Dan Norths CUPID lieber. Als Eigenschaften für joyful coding wirkt es auf mich praktischer als SOLID
  • 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 würde bei so einer Website sofort weitergehen, weil ich annehme, dass die Person, die die Seite vibe-coded hat, wahrscheinlich auch das Buch vibe-coded hat. Außerdem habe ich mir die Coding-Historie dieser Person angesehen, und die besteht vor allem aus Cheatsheets und Roadmaps, weshalb ich dem Buchinhalt kaum Vertrauen entgegenbringen kann
    • Ich erwarte außerdem, dass die Domain natürlich einfach der lange Titel mit .com sein wird
  • 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 mag dieses Gesetz wirklich sehr und wünschte, mehr Leute würden es verstehen. Management und Business wollen im Voraus planen, aber in Software lassen sich nicht alle Probleme von Anfang an vorhersagen. Statt sich mit einer von Beginn an starren Struktur selbst einzusperren, halte ich es für effektiver, Probleme auf einer flexiblen Architektur durch Refactoring zu lösen
    • Allgemein halte ich iterative Entwicklung für besser als übervorsichtige Entwicklung. Das Beispiel mit dem Kampfjet-Steuerknüppel war sehr fein und sehr gut. Dadurch musste ich an ein schmerzhaftes Uni-Projekt denken, bei dem die Build-Zeit zehn Minuten betrug. Wir hätten statt der echten Implementierung bereitgestellte Mock-Komponenten verwenden sollen, aber ich habe das zu spät bemerkt und es deshalb nicht vor der Deadline geschafft. Seitdem suche ich immer zuerst nach Wegen, die Build-Zeit zu verkürzen
    • Wenn man Boyd's Gesetz zu weit treibt, landet man meiner Meinung nach auch mal bei Formen wie einwöchigen Sprints oder noch weniger
  • 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 finde allerdings auch den Vorschlag "mach doch eine Wikipedia-Seite" etwas seltsam. Wikipedia im Jahr 2026 wirkt auf mich wie ein Ort, an dem neue Seiten praktisch nur noch von tiefen Experten der Wikipedia-Kultur erstellt werden können. Wiki-Profis sagen zwar, jeder könne eine Seite anlegen, wenn man nur 137 Richtlinien befolge, aber in der Realität hängt immer dieser zynische Eindruck in der Luft, dass ein Admin sie sowieso wieder löscht
    • Ich würde dieses Gesetz Slop's Law nennen. Wenn etwas schlampig gebaut werden kann, wird es am Ende auch schlampig gebaut
    • Als Sturgeon's Law für 2026 würde ich zusammenfassen: "99% von allem ist crap oder slop"
  • 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 denke, das Law of Unintended Consequences aus der Liste beschreibt dasselbe Phänomen ebenfalls gut. Trotzdem gefällt mir persönlich die Geschichte mit dem Zaun besser
    • Ich nehme dieses Prinzip als eines meiner Kernprinzipien und würde es in einem Satz als erst denken, dann handeln zusammenfassen
  • 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