Kolumne: Stropek as a Service

Zwiebeln bringen mich zum Heulen – Warum man es mit den Abstraktionsschichten auch übertreiben kann
Keine Kommentare

Entwicklerinnen und Entwickler lieben Abstraktionsschichten. Schnittstellen und abstrakte Basisklassen, Dependency Injection, Factories – diese Liste an Mechanismen zur Entkopplung von Komponenten und zum Abstrahieren von konkreten Implementierungen könnte man lange fortsetzen. Wie bei Zwiebeln stapeln sich Schichten über Schichten, damit alles im Fall des Falles ausgetauscht werden kann.

Anstatt aber mein Softwarearchitektenherz höher schlagen zu lassen, bringen mich solche Zwiebeln oft zum Heulen. Wir vergessen bei der Softwareentwicklung manchmal, dass der Aufbau des Codes auch zur Größe und Komplexität des Projekts passen muss. In dieser Ausgabe meiner Kolumne möchte ich zum Hinterfragen von Abstraktionsschichten anregen. Starten wir, indem wir einige Gründe für die vielen Abstraktionsschichten beleuchten.

Lock-in-Effekt

Jeder, der längere Zeit in der Softwareentwicklung tätig war, kann Geschichten davon erzählen, wie Bibliotheken, Frameworks, Programmiersprachen oder Tools, die man tief in die eigene Lösung integriert hatte, einen mehr oder weniger schnellen Tod gestorben sind. Plötzlich saß man da mit einer Menge Code, in den die nicht mehr gewartete Komponente fest verwoben war. Die Alternativen in so einer Situation sind alle unangenehm. Ausbauen bedeutet eine Menge Arbeit, ohne dass die Kunden funktional einen Vorteil sehen. Nichts tun klappt vielleicht eine gewisse Zeit, ist aber keine Dauerlösung.

In Zeiten von Cloud und PaaS ist die Lage noch verzwickter. Wenn der Anbieter eines Service entscheidet, ihn einzustellen, kann man nicht auf Zeit spielen. Der Service wird irgendwann einfach verschwinden und die eigene SaaS-Lösung mit in die Tiefe reißen. Im Gespräch mit Entscheidungsträgern wird auch häufig die Angst vor Preisänderungen bei Cloud-Services als Grund genannt, warum man immer bereit für einen Wechsel sein sollte.

Es ist die Angst vor dem Lock-in-Effekt, der dazu führt, dass wir Software so schreiben wollen, dass wir Komponenten leicht austauschen können. Wenn es zum Fall der Fälle kommt, soll uns der Wechsel keine große Mühe machen – das wäre zumindest der Plan…

Isolieren von Änderungen

Manche Teams versuchen, sich durch Abstraktionsschichten vor Änderungen in der eigenen Software zu schützen. Das Ziel ist, dass man Module austauschen oder überarbeiten kann, ohne den Rest der Software anfassen zu müssen. Das soll den Aufwand für das Testen und das Risiko des Einschleichens von Fehlern reduzieren.

In der Cloud geht man noch einen Schritt weiter. Man packt Module in getrennte Services und lässt sie über Web-APIs, Messaginginfrastruktur, WebHooks etc. kommunizieren. Das reduziert die Kopplung noch weiter und soll zu leicht austauschbaren Softwarekomponenten (Microservices) führen.

Kundenwünsche

Ein weiterer Grund für Abstraktionsschichten sind Kundenwünsche. Der eine Kunde verwendet ein relationales Datenbankmanagementsystem, der nächste will aber NoSQL. Der eine will diesen Logger, der andere Kunde will einen anderen. Durch Abstraktionen versuchen wir, Flexibilität und Konfigurierbarkeit in unsere Softwarelösungen zu bringen.

Cloud-Computing macht die Sache nicht einfacher, im Gegenteil. Jedes Team, das Standardsoftware anbietet, erzählt mir die gleiche Geschichte: Wenn wir voll auf die Cloud setzen, verlieren wir Kunden. Also baut man Software, die beides kann (bzw. könnte), Cloud und On Premises. In der Cloud verwendet sie die einen und On Premises die anderen Basisdienste. Wenn man sich zur Nutzung fertiger PaaS-Dienste durchringt, die nur in einer Cloud angeboten werden, dann müssen diese unbedingt wegabstrahiert werden. Es könnte ja sein, dass man mal zu einem anderen Cloud-Provider wechseln oder die Software beim Kunden installieren will.

Abspecken!

Ich möchte dazu aufrufen, abzuspecken, selbst erfundene Schichten und Abstraktionen zu hinterfragen und schlankere Software zu bauen. Bitte nicht falsch verstehen! Abstraktionsschichten sind oft sinnvoll. Ich sehe in meiner Beratungspraxis aber viele Teams, die es hoffnungslos übertreiben. Meiner Ansicht nach sollte man sich bei jeder Abstraktion ein paar Fragen stellen:

  • Gibt es einen konkreten Anwendungsfall für die Abstraktion oder versuche ich mich nur auf eine theoretische Situation vorzubereiten, von der ich nicht weiß, ob sie jemals eintritt und wie sie im Endeffekt aussehen wird?
  • Welche Funktionen der zugrunde liegenden Komponente verliere ich durch die Einführung einer Abstraktionsschicht? Diese Frage sollte man sich besonders bei Abstraktionsschichten stellen, die man über fertige Drittanbieterkomponenten oder Cloud Services stülpt.
  • Welche Auswirkung hat die Abstraktion auf die Performance des Systems? Fast jede Abstraktionsschicht bezahlt man mit mehr oder weniger großen Performanceeinbußen. Das gilt nicht zuletzt bei feingranularen Microservices.
  • Kann ich heute schon abschätzen, ob meine Abstraktion, die mir eine hypothetische Veränderung in der Zukunft leichter machen soll, überhaupt passend sein wird, wenn es soweit kommen sollte?
  • Bin ich mir sicher, dass der Aufwand für Entwicklung und Wartung der Abstraktionsschicht nicht höher ist, als der Aufwand, den ich im Fall eines (vielleicht nie eintretenden) Komponententauschs hätte? Wir hatten es kürzlich mit einem Softwaresystem zu tun, in dem das Hinzufügen eines Feldes zu einer bestehenden Tabelle Codeänderungen in neun (!) Schichten notwendig gemacht hat. Das erhöht die Wartungskosten spürbar. Zahlt es sich aus?
  • Passen meine Abstraktionsschichten zur Größe und Komplexität des Projekts? Bildlich gesprochen: Nicht jedes Hello-World-Programm muss Console wegabstrahieren.
  • Gute Abstraktionen zu entwickeln, ist aufwendig und erfordert viel technische und inhaltliche Erfahrung. Habe ich das notwendige Wissen? Bin ich bereit, den notwendigen Aufwand zu investieren? Schlechte Abstraktionen richten oft mehr Schaden an, als sie nützen.
  • Abstraktionsschichten sind dazu da, mich vor Änderungen zu schützen. Insofern sind sie von Natur aus langlebig. Fühle ich mich wohl bei dem Gedanken, dass mich die Abstraktion für eine sehr lange Zeit begleiten wird? Werde ich die Möglichkeit haben, die Abstraktionsschicht zu überarbeiten, wenn sich im Lauf der Zeit die Anforderungen ändern?
  • Rechtfertigt die Erreichbarkeit einer größeren Kundengruppe durch höhere Flexibilität den Zusatzaufwand für die Entwicklung und Wartung der Abstraktionsschicht? Hätte eine spezialisierte und dadurch schlankere und kostengünstigere Lösung nicht das gleiche oder vielleicht sogar größeres Marktpotenzial? Das ist speziell relevant bei der Frage, ob eine Software Cloud-native oder als Hybridlösung entwickelt werden soll.

Gute Abstraktionen

Natürlich gibt es eine Menge Situationen, in denen Abstraktionen Sinn ergeben und keineswegs abzulehnen sind. Hier einige Beispiele:

  • Es gibt tatsächlich konkrete Anwendungsfälle, die die Abstraktion notwendig machen.
  • Die Abstraktion basiert auf einem Industriestandard, der weit verbreitet und von hoher Qualität ist.
  • Man nutzt eine fertige Abstraktionsschicht, die die jeweilige Plattform oder Komponente mitbringt. Solche Abstraktionen sind häufig gut überlegt und haben sich in vielen Anwendungsfällen bewährt.
  • Die Abstraktion erleichtert die Entwicklung automatisierter Tests. Aber Vorsicht: Ich kann die vielen Codereviewprojekte nicht mehr zählen, bei denen mir Teams erklärt haben, wie sie durch Abstraktionsschichten und Dependency Injection perfekt testbare Software gebaut haben. Im nächsten Atemzug sagten sie mir, dass sie leider am Ende kein Zeitbudget mehr hatten, tatsächlich automatisierte Tests zu entwickeln. Etwas weniger Schichten und dafür ein paar wichtige, automatisierte Tests wäre sinnvoller.
  • Man entwickelt eine Plattform, auf die andere Entwicklungsteams aufbauen. Die Abstraktionsschicht ermöglicht es der Plattform, Funktionen anzubieten, ohne zum Entwicklungszeitpunkt die Details der verschiedenen Implementationen zu kennen.

Dem Abstraktionsfetisch vorbeugen

Eine Möglichkeit, übertriebenem Hang zu Abstraktionen vorzubeugen, ist meiner Erfahrung nach, den geforderten Reifegrad bezüglich Konzeption und Dokumentation zu erhöhen. Für Abstraktionsschichten müssen besonders hohe Qualitätskriterien gelten. Hier einige Beispiele:

  • Die erhöhten Kosten dürfen nicht durch ein Bauchgefühl, sondern müssen durch konkrete, niedergeschriebene Fallbeispiele und Kalkulationen gerechtfertigt werden.
  • Abstraktionen müssen schon in der Konzeptionsphase getestet werden. Können tatsächlich alle Anwendungsfälle abgebildet werden? Ist die Abstraktion passend für alle absehbaren Implementationen?
  • Man sollte auf jeden Fall mehrere Lösungsvarianten ausarbeiten und diskutieren. Die erste Idee ist nicht immer die beste. Meiner Erfahrung nach tendieren viele Teams dazu, zu schnell Code zu schreiben. Speziell bei so wichtigen Themen wie Abstraktionen, die in vielen Bereichen einer Softwarelösung zum Einsatz kommen, sollte man ausreichend Zeit für die Konzeption und Diskussion einplanen.
  • Durch Prototypen kann untersucht werden, ob die Performanceauswirkungen der Abstraktionsschicht akzeptabel sind beziehungsweise wie hoch der Mehraufwand für Gegenmaßnahmen (z. B. Caches) ist.
  • Abstraktionsschichten müssen überdurchschnittlich gut dokumentiert sein.

Fazit

Abstraktionen sind per se nichts Schlimmes, ganz im Gegenteil. Selbst eine Abstraktion mit kleinen Makeln ist wünschenswert, wenn sie tausende Zeilen Spaghetticode verhindert. Viele Entwicklungsteams haben aber einen Hang zum Over-Engineering und der wird nicht selten in Abstraktionsschichten ausgelebt. Mein Appell lautet, dass selbst erfundene Abstraktionsschichten mehr hinterfragt werden sollten. Sie müssen zur Größe des Projekts passen und konkrete Probleme lösen.

Lesen Sie alle Ausgaben der Kolumne „Stropek as a Service„!
In der Kolumne greift Rainer Stropek spannende Aspekte wie die Finanzierung, den Customer Lifetime Value, aber auch wichtige Themen wie Billing, Kundenbindung durch Qualität oder APIs auf – alles aus der Sicht eines Unternehmers, der seit 20 Jahren in der IT-Branche tätig ist und seit fünf Jahren intensive Erfahrungen mit SaaS gesammelt hat.
Unsere Redaktion empfiehlt:

Relevante Beiträge

Hinterlasse einen Kommentar

Hinterlasse den ersten Kommentar!

avatar
400
  Subscribe  
Benachrichtige mich zu:
X
- Gib Deinen Standort ein -
- or -