Wie Engineering Prinzipien mir helfen, hochwertige Software zu entwickeln
In den letzten Jahren sind Software-Entwickler nachlässig geworden, insbesondere im Vergleich zur Rigorisität und Präzision traditioneller Ingenieursdisziplinen. Meiner Meinung nach ist ein wesentlicher Grund dafür, dass sich die Softwareentwicklung zunehmend von physikalischen Beschränkungen entkoppelt hat.
Früher als die Rechenleistung knapp war, mussten Softwareingenieure oft intensiv über bestimmte Probleme nachdenken. Der drastische Anstieg der Rechenleistung und der verfügbaren Daten hat dazu geführt, dass Softwareingenieure nachlässig wurden und das Design eines Algorithmus kaum mehr eine Rolle spielt.
Inzwischen sind die niedrigen Standards unter Softwareingenieuren sogar zu einem Meme geworden. Programmierer geben häufig zu, dass sie auf Google, Stack Overflow und ChatGPT zurückgreifen, um Probleme zu lösen, und sich dabei oft auf das Copy und Paste von Code verlassen, ohne dessen Qualität oder Eignung gründlich zu prüfen.
Ich persönlich bewundere die Rigorisität und Präzision traditioneller Ingenieure. In den letzten Jahren bin ich zu der Erkenntnis gelangt, dass ich Prinzipien aus dem traditionellen Ingenieurwesen übernehmen und auf die Softwareentwicklung anwenden kann, um die Qualität meiner Softwareprodukte erheblich zu verbessern.
Systemdenken
Ein solches Prinzip ist der Ansatz des Systemdenkens. Das sogenannte "Systems Engineering" involviert die Integration verschiedener imperfekter Teilsysteme in ein Gesamtsystem, das ein sogenanntes Emergent Behavior ermöglicht. Nehmen wir als Beispiel die Luftfahrttechnik. Ein Luftfahrtingenieur muss verschiedene unvollkommene Teilsysteme, von denen keines allein flugfähig ist, zu einem ganzheitlichen System integrieren, welches fliegen kann – zum Beispiel mechanische Systeme, Elektronik, Softwaresysteme, Materialien usw.
Als Softwareentwickler entwickle ich zwar keine Flugzeuge, aber ich integriere verschiedene imperfekte Teilsysteme in ein ganzheitliches System, wie Hardware und Software, Frontend und Backend, die jeweils aus vielen Unterkomponenten und Layers bestehen. Ähnlich wie in der Luftfahrttechnik muss ich nicht nur die Eigenschaften jedes Teilsystems berücksichtigen, sondern auch wie diese verschiedenen Teilsysteme miteinander interagieren.
Denken ausgehend von First Principles
Ein weiteres entscheidendes Ingenieursprinzip ist das Denken von First Principles. Dabei handelt es sich um eine Methode, bei der ein komplexes Problem in grundlegende Annahmen zerlegt wird, aus denen ein Ingenieur durch deduktives Schließen Schlussfolgerungen ableitet – eine Technik, die besonders dann beliebt ist, wenn es um neue Probleme geht, mit denen bisher niemand konfrontiert war.
In den meisten meiner großen Projekte stoße ich auf sehr schwierige Probleme, die ich nur lösen konnte, indem ich ausgehend First Principles dachte. Wenn ich mich tagelang in einer Sackgasse befinde und keine Lösung in Sicht ist, denke das Problem von Grund auf neu durch und versuche, einen anderen Ansatz zu finden. Oft führen diese Überlegungen zu Lösungen, die sich erheblich von meinem ursprünglichen Ansatz unterscheiden, sich jedoch letztendlich als die bessere Lösung herausstellen.
Denken in Trade-Offs
Ingenieure stehen oft vor sogenannten Trade-Offs, bei denen ein bestimmter Vorteil mit Kosten oder einem Nachteil verbunden ist. Oder wie es der Ökonom Thomas Sowell einmal sagte: „Es gibt keine Lösungen, nur Trade-Offs“ – die meisten Ingenieure sind sich dieser Tatsache voll bewusst. Höhere Qualität impliziert in der Regel höhere Kosten, bessere Leistung erfordert oft mehr Ressourcen oder höhere Geschwindigkeit bedeutet geringere Genauigkeit. Mit anderen Worten: Die physikalische Welt setzt Ingenieuren und ihren Designs Grenzen.
In ähnlicher Weise haben auch Softwareingenieure mit Trade-Offs zu tun, wie etwa zwischen Effizienz und Resilienz, Benutzerfreundlichkeit und Sicherheit, Skalierbarkeit und Einfachheit, Standardisierung und Anpassung oder zwischen Flexibilität und Komplexität. Das Bewusstsein für diese Trade-Offs hilft mir, Vor- und Nachteile auf eine systematische und strukturierte Weise abzuwägen.
Neigung zur Komplexitätsreduktion
Ein weiteres wichtiges Ingenieursprinzip, das ich häufig in der Softwareentwicklung antreffe, ist die Tendenz, Komplexität zu vermeiden. Komplexität kann oft zu großen Problemen führen, wie z.B. Instabilität, Unknown Unknowns oder Herausforderungen bei der Wartung eines Systems. Auch hier kann die Luftfahrttechnik als Beispiel herangezogen werden. Einige Luftfahrtingenieure schlagen sogenannte "Morphing Wings" vor – Flügel, die aus beweglichen Teilen bestehen und potenziell die Manövrierfähigkeit und aerodynamische Effizienz von Flugzeugen verbessern könnten. Das Problem dabei ist jedoch, dass Morphing Wings eine erhebliche Komplexität in das Flugzeug einbringen, was ein Risiko für die Stabilität des Gesamtsystems darstellen könnte.
Softwareingenieure befinden sich oft in ähnlichen Situationen. Das Hinzufügen von Komplexitäten zu einer Software kann attraktiv sein, da sie mehr oder bessere Funktionalitäten ermöglichen. Das Problem ist jedoch, dass diese Komplexitäten zu Instabilitäten führen können oder schwer zu warten und zu debuggen sind. Während in einigen Fällen Komplexitäten lohnenswert sein können, führen sie in vielen anderen Fällen jedoch zu erheblichen Problemen.
Fazit
Dies sind nur die wichtigsten Ingenieurprinzipien, die Softwareentwickler berücksichtigen sollten, aber es gibt noch viele weitere faszinierende Konzepte, die Softwareingenieure nutzen könnten, um die Qualität ihrer Software zu verbessern, wie das Konzept der Redundanz, modulare Designs, der iterative Prozess zur Systemoptimierung, Sicherheitsmargen oder nutzerzentrierte Designs.