Softwarearchitektur: Der Mythos der Wiederverwendung
Mit jedem neuen Architekturkonzept – sei es Modularisierung, OOD, CBD oder aktuell SOA – wird immer wieder Wiederverwendung als einer der wichtigsten Gewinne angepriesen. Nach einer Weile der begeisterten Anwendung des Paradigmas wird dann meist ernüchtert festgestellt, dass der Einsatz doch nicht zu der gewünschten Wiederverwendung und den dadurch versprochenen Einspareffekten geführt hat. Es folgen eine enttäuschte Abkehr vom Konzept und die Suche nach dem nächsten Heilsversprechen. Dieser Artikel erklärt, warum Wiederverwendung das falsche Versprechen ist und wo die wahren Einsparpotenziale liegen.
Der Mythos Wiederverwendung: „Design für Wartung” als eigentliches Ziel
Veröffentlicht in "ObjektSpektrum", 7/2009
Hier gibt's noch mehr spannende Infos von uns für euch
Gemeinsam bessere Projekte umsetzen.
Wir helfen deinem Unternehmen.
Du stehst vor einer großen IT-Herausforderung? Wir sorgen für eine maßgeschneiderte Unterstützung. Informiere dich jetzt.
Hilf uns, noch besser zu werden.
Wir sind immer auf der Suche nach neuen Talenten. Auch für dich ist die passende Stelle dabei.
Wiederverwendung: Versprechen und Realität
Voraussetzungen für erfolgreiche Wiederverwendung
Wartung: Die eigentliche Herausforderung
Design for Maintenance
Einschränkungen und Fallstricke
Tipps für die Praxis
Zusammenfassung
Literatur & Links
Uwe Friedrichsen
CTO
Möchtest du dich mit mir austauschen?
Wiederverwendung: Versprechen und Realität
Eines der großen Versprechen der serviceorientierten Architektur (SOA) sind mittelfristige massive Kosteneinsparungen durch einen hohen Grad der Wiederverwendung (Re-Use) von Services. Mit diesem Versprechen steht SOA in der Tradition z. B der objektorientierten Softwareentwicklung (Object Oriented Design, OOD) oder der komponentenorientierten Softwareentwicklung (Component Based Design, CBD): Durch die saubere Kapselung von Funktionalität lassen sich in unterschiedlichen Kontexten wiederverwendbare Bausteine – seien es Klassen, Komponenten oder Services – realisieren. Diese Funktionalität muss in zukünftigen Projekten nicht mehr neu entwickelt werden, wodurch sich mittelfristig die erhöhten Anfangsinvestitionen für die Einführung des neuen Paradigmas nicht nur amortisieren, sondern hohe Kosteneinsparungen entstehen.
Diese Re-Use-Argumentation hat man in den letzten Jahren in dieser oder leicht abgewandelten Varianten regelmäßig als wichtiges Argument für die Einführung einer SOA gehört und hört sie teilweise immer noch. Damit reiht sich SOA nahtlos in die Tradition aller Paradigmen zur modularen, schnittstellenorientierten Strukturierung von Softwaresystemen ein. Jedes dieser Paradigmen war und ist untrennbar mit der Re-Use-Argumentation verbunden. In der Vergangenheit stellte man nach einiger Zeit immer wieder ernüchtert fest, dass sich die Versprechen der massiven Wiederverwendung von Softwarebau steinen nicht erfüllt hatten. Die erhöhten Anfangsinvestitionen wurden getätigt, aber die versprochenen Amortisationseffekte traten nicht ein, was zu großer Skepsis gegenüber dem jeweiligen Paradigma – bis hin zur offenen Ablehnung – führte, insbesondere in den Reihen der Entscheider, die die erhöhten Investitionen im Vertrauen auf die versprochene, spätere Amortisation genehmigt hatten. Auch im Kontext von SOA mehren sich mittlerweile die kritischen Stimmen. Erfahrungen aus größeren SOA-Projekten führten zu der Erkenntnis, dass der Grad der Service-Wiederverwendung vernachlässigbar gering ist (vgl. z. B. [Jos09]). Die Geschichte droht sich also einmal mehr zu wiederholen.
Voraussetzungen für erfolgreiche Wiederverwendung
Was sind die Gründe dafür, dass Wiederverwendung nicht funktioniert? Auf diese Frage gibt es mehrere Antworten. Häufig wird fälschlicherweise angenommen, dass alleine die Verwendung eines Paradigmas, das die Kapselung von Verantwortlichkeiten in „Bausteinen” – seien es Module, Objekte, Komponenten oder Services – zum Inhalt hat, ein Garant für eine erfolgreiche Wiederverwendungskultur ist. Diese Annahme ist falsch. Der Einsatz eines Paradigmas, das eine Kapselung von Verantwortlichkeiten in Softwaremodulen bietet, ermöglicht die Wiederverwendung von Software zwar, garantiert diese aber in keinster Weise.
Befasst man sich genauer damit, welche weiteren Rahmenbedingungen für eine erfolgreiche Software-Wiederverwendung erfüllt sein müssen, stellt man fest, dass Wiederverwendung in erster Linie ein organisatorisches und unternehmens-soziologisches Thema ist.
In [Pri97] wird beispielsweise anschaulich dargelegt, dass eine entsprechende Unternehmensorganisation und zugehörige Unternehmenskultur Voraussetzung für eine gezielte und systematische Wiederverwendung von Software ist, wie sie für die Realisierung von Einsparpotenzialen benötigt wird. In [Kav97] werden diese Aussagen noch weiter präzisiert und es wird eine Wiederverwendungs-Reifegrad- Matrix (Re-Use-Maturity-Matrix) eingeführt.
In dieser Matrix werden Artefakte für eine gezielte Wiederverwendung in Beziehung zur Unternehmensorganisation und -kultur im Sinne des CMM(I) Levels (Capability Maturity Model Integration, vgl. [SEI09]) des Unternehmens gesetzt. Aus der aufgestellten Matrix lässt sich ablesen, dass eine Wiederverwendung von Services im Sinne einer SOA einen sehr hohen CMM(I)-Level voraussetzt, den die meisten Unternehmen inhaltlich nicht erfüllen dürften. Auch wenn CMM(I) mittlerweile vielfach eher kritisch gesehen wird, besteht dennoch ein direkter Zusammenhang zwischen der Unternehmensorganisation und -kultur und einer erfolgreichen möglichen Wiederverwendung.
Abbildung 1 ist eine verfeinerte und aktualisierte Darstellung der Re-Use- Maturity-Matrix in Form eines Re-Use- Maturity-Graphen. Neben der Organisations ebene des Unternehmens (rechte Achse) beeinflussen die Granularität des Bausteins (untere Achse) und seine Domänen zuordnung (obere Achse) den Grad der erreichbaren Wiederverwendung (Grad der Schraffierung) unter Berücksichtigung des Abstraktionsgrades des Bausteins (linke Achse). Exemplarisch sind zusätzlich einige typische Bausteine eingetragen. Es ist direkt zu sehen, dass z. B. ein Business-Service im Sinne einer SOA wesentlich schwieriger wiederzuverwenden ist als eine einfache Klassenbibliothek.
Es muss eine Organisation etabliert und finanziert werden, die über das reine Erreichen von Projektzielen (Zeit, Budget, Qualität) hinaus das Identifizieren, Konsolidieren, Verfeinern, Bereitstellen und Vermarkten von wiederverwendbaren Bausteinen unterstützt. Neben der reinen Identifikation und Bereitstellung von wiederverwendbaren Bausteinen sind hier insbesondere die Aufwände für das Konsolidieren und Verfeinern eines Bausteins zu berücksichtigen. Die Aufarbeitung eines Projektartefakts zu einem systematisch wiederverwendbaren Baustein entspricht inhaltlich der Aufarbeitung eines Projektartefakts zu einem Produkt, das extern verkauft werden soll.
Dazu sagt Fred Brooks: „Producing a product takes about 9 times as much effort as implementing its components individually for internal use (productization adds a factor of 3, integration and test adds a factor of 3)” (vgl. [Bro95]). Dieses kurze Zitat bringt zum Ausdruck, dass die Herstellung eines systematisch wiederverwendbaren Bausteins einen erheblich höheren Aufwand bedeutet als die reine Implementierung im Rahmen eines Projekts. Diese Mehraufwände können typischerweise nicht im Rahmen des den Baustein initial produzierenden Projekts erbracht werden, da dieses normalerweise weder über die Zeit noch über das Budget für die notwendige Überarbeitung verfügt.
Auf Ebene der Unternehmenskultur ist es notwendig, eine Abkehr vom verbreiteten NIH-Syndrom (Not Invented Here) zu etablieren. Dieses Syndrom besagt, dass insbesondere Softwareentwickler wesentlich lieber selbst eine neue – oftmals nur mittel mäßig gute – Lösung entwickeln, anstatt zu prüfen, ob es bereits vorhandene Lösungen gibt, die sie wiederverwenden können. Nebenbei müssen aufbereitete, wiederverwendbare Bausteine auch, wie zuvor beschrieben, im Unternehmen vermarktet werden, damit ein Entwickler darauf aufmerksam werden kann.
Neben dem grundsätzlichen, verbreiteten Misstrauen eines Softwareentwicklers gegenüber Code, den er nicht selbst entwickelt hat, unterstützt auch die Projektkultur dieses Vorgehen: Für einen Entwickler ist leichter absehbar und planbar, was es für ihn bedeutet, eine Funktionalität neu zu entwickeln, als die Integration einer vorhandenen, fremden Software. Insbesondere wenn die fremde Software nicht entsprechend zu einem wiederverwendbaren Produkt aufbereitet wurde, kann ein Softwareentwickler dem Projektleiter mit seinen Zeit- und Budget- Anforderungen besser Auskunft geben, wenn er die benötigte Funktionalität selber entwickelt. Letztlich hat die Wiederverwendung noch mit einem weiteren Problem zu kämpfen. Es ist wünschenswert, möglichst große, grob-granulare Bausteine (z. B. Services und Komponenten) wiederzuverwenden, damit der Effekt aus der Wiederverwendung möglichst hoch ist. Es gilt: Je größer und höherwertiger ein Baustein ist, desto mehr ist er bei sauberem Architekturentwurf an der zugehörigen Fachdomäne ausgerichtet. Eine Fachdomäne tendiert aber dazu, aufgrund der für heutige Wettbewerbsfähigkeit notwendigen Effizienz praktisch kaum noch Redundanzen aufzuweisen. Hat man also einen Baustein entwickelt, der ein domänenbezogenes Stück Fachlogik adäquat kapselt, wird dieser per se nicht wiederverwendet, weil er auch in der realen Welt nur an einer Stelle benötigt wird. Auch das ist ein Grund dafür, warum sich – zumindest bei guter Architektur – kleine und eher technisch orientierte Bausteine deutlich besser wiederverwenden lassen als große, fachlich orientierte Bausteine.
Wartung: Die eigentliche Herausforderung
Wenn ein Architekturkonzept wie SOA also nicht bzw. nur mit großen Zusatzaufwänden Wiederverwendung und die damit verbundenen Einsparpotenziale ermöglicht, stellt sich die Frage: Wofür das alles? Die versprochenen Einsparungen gibt es nicht bzw. nur mit großem Aufwand in ferner Zukunft. Haben wir es hier nur mit einer Schrulle strukturverliebter Architekten zu tun oder worin liegt der Nutzen schnittstellenbasierter Kapselung? Die einfache Antwort ist: Eine schnittstellenbasierte Kapselung von Verantwortlichkeiten bringt sehr viel, nur lenkt die Re- Use-Argumentation den Blick in die falsche Richtung. Der Nutzen entsteht nämlich nicht in der Entwicklung einer Funktionalität (Construction), sondern in der Wartung (Maintenance). Unter Wartung ist nicht nur das Beheben von Fehlern zu verstehen, sondern auch die Weiterentwicklung der Software, d. h. die Anpassung an neue fachliche und technische Anforderungen. Betrachtet man die Ergebnisse entsprechender Studien, wie sie z. B. in [Kos03] anschaulich zusammengefasst sind, stellt man fest, dass heutzutage zwischen 70 % und 90 % der IT-Budgets für die Wartung und Weiterentwicklung von Software aufgewendet wird – Tendenz steigend. Anders ausgedrückt: Nur 10 % bis 30 % der ITBudgets gehen in die Entwicklung neuer Software, während der große Rest in die Pflege bestehender Software investiert wird (siehe auch Abb. 2).
Dieses Verhältnis verdeutlicht, dass die größten Kostenfallen und damit auch die größten Einsparpotenziale der Softwareentwicklung nicht in der Neuentwicklung von Funktionalität, sondern in der Pflege und Weiterentwicklung liegen. Wenn man es schafft, die Software so zu konzipieren und zu entwickeln, dass dieser Kostenblock kleiner wird, kann man damit echte Kosteneinsparungen erzielen.
Die Fokussierung auf die Kostensenkung in der Softwareentwicklung führt hingegen nur zu geringen Einspareffekten. Das ist eine der größten Fehlinterpretationen in der typischen Argumentation bezüglich der Software-Wiederverwendung: Das Ziel muss nicht Design for Re-Use, sondern Design for Maintenance sein.
Design for Maintenance
Was bedeutet das z. B. für eine SOA bzw. – im übertragenen Sinne – für in gewisser Weise vergleichbare Paradigmen wie CBD und OOD? Einfach ausgedrückt müssen Services so geschnitten werden, dass die Wartungsaufwände möglichst gering sind. Das klingt zunächst trivial, erweist sich in der Praxis aber als sehr schwierig. Wie erreicht man das?
Der Ansatz hierfür besteht darin, die Änderungsanforderungen zu beobachten und die Struktur der Software an den am häufigsten auftretenden Änderungsanforderungen, den Dynamics of Change, auszurichten. Üblicherweise richtet sich die Struk turierung einer Software an Kriterien aus, die eine möglichst effiziente Entwicklung erlauben. Diese Strukturen ermöglichen aber nicht zwangsläufig eine möglichst effiziente Pflege. Das bedeutet:
Ein kleines Beispiel zur Erläuterung, das wahrscheinlich jeder von uns aus eigener Erfahrung kennt: Schichtenarchitekturen sind in den heutigen Softwaresystemen omnipräsent. Systeme werden in mehrere Schichten untergliedert, wie z. B. „Präsen tation”, „Geschäftslogik” und „Persistenz” (häufig sind es noch mehr). Über alle Schichten hinweg werden Datenstrukturen im Rahmen der verschiedenen Operationen transportiert und an den Schich - tengrenzen zugunsten einer Entkopp lung der Schichten voneinander auch transformiert.
Diese Architektur ist für die Entwicklung eines Systems gut geeignet. Einzelne Entwicklungsteams mit dem entsprechenden Spezialwissen, z. B. für GUI-Entwicklung, RDBMS-Zugriff oder Adapter- Programmierung, können die einzelnen Bausteine weitestgehend unabhängig voneinander entwickeln, womit sich die vorhandenen Entwicklerkapazitäten recht zielgenau planen und einsetzen lassen.
Sind die typischen Anforderungen für ein solches in Schichten strukturiertes System allerdings Änderungen an den Datenstrukturen, getrieben durch entsprechende fachliche Anforderungen, ist die Schichtenarchitektur eher kontraproduktiv. Für jede Datenstruktur-Änderungsanforderung muss eine ganze Reihe Bausteine geändert werden, Schnittstellen werden geändert, die Änderungen sind nicht-lokal. Die für die Entwicklung gut geeignete Schichtenarchitektur erweist sich in dem Beispiel aufgrund der Art der Änderungsanforderungen als nicht gut geeignet1).
An diesem einfachen Beispiel wird klar, dass eine für die Softwareentwicklung gute Struktur nicht unbedingt eine gute Struktur für deren Pflege ist. Um eine für die Pflege gute Strukturierung zu erhalten, muss man die Dynamics of Change betrachten.
Aber wie identifiziert man zukünftige Änderungsanforderungen? In der Regel kennt man sie nicht und betrachtet daher üblicherweise die Anforderungen der Vergangenheit in der Erwartung, dass vergleichbare Anforderungen auch in Zukunft gestellt werden. (In den „Tipps für die Praxis” weiter unten im Artikel finden sich noch Empfehlungen für weitere Indikatoren für zukünftige Änderungsanforderungen.)
Diese Änderungsanforderungen sind dann bezüglich ihrer Auswirkungen auf die IT-Systeme zu bewerten. Bedeuten sie am ehesten Änderungen an Daten, an Funktionen oder an Prozessen? Wie muss ich meine Software und meine Services schneiden, damit die Änderungen möglichst lokal bleiben, also so, dass ich die Änderungen innerhalb eines Service möglichst oft ohne Änderung der Service-Schnittstelle umsetzen kann?
Die Auseinandersetzung mit diesen Fragen führt in letzter Konsequenz zu einer Veränderung des Architektur entwurfs: Normalerweise erfolgt dieser statisch, d. h. die bekannten Anforderungen werden analysiert und dafür wird eine geeignete Lösungsarchitektur entworfen. Eine solche Vorgehensweise ermöglicht eine gewisse Breite an Lösungsarchitekturen, wobei in der Regel diejenige Lösung gewählt wird, die die Erstellung der Software am besten unterstützt. Oft führt ein solcher Entwurf aber zu einer bezüglich den Änderungsanforderungen ungünstigen Architektur (siehe Abb. 3, oberer Teil).
Die zusätzliche Berücksichtigung der zu erwartenden Änderungsanforderungen über die Zeit führt zu einem dynamischeren Architekturentwurf. Bei diesem wird der Fokus nicht mehr primär auf die Erstellung der Software gelegt, sondern auf ihre Veränderung über die Zeit. In diesem Fall wird eine Lösungsarchitektur gewählt, die die Dynamics of Change, also die Änderungen der Software über die Zeit, möglichst optimal unterstützt (siehe Abb. 3 unterer Teil).
Einschränkungen und Fallstricke
Die Dynamics of Change beschreiben die am häufigsten auftretenden Änderungsanforderungen. Es ist nicht möglich, allen Änderungsanforderungen optimal gerecht zu werden, da manche Anforderungen – isoliert umgesetzt – zu sich gegenseitig widersprechenden Strukturierungen führen. Es gibt also nicht die optimale Struktur für alle Anforderungen, sondern nur eine Struktur, die die Dynamics of Change möglichst gut unterstützt (siehe Abb. 4).
Eine weitere Einschränkung bezieht sich auf die Analyse der Änderungsanforderungen und deren Auswirkungen auf die ITSysteme. Wendet man das Prinzip konsequent an, dass alle Änderungen lokal bleiben sollen und keine Schnittstellen verändert werden, führt das zwangsläufig zu einem großen Service, der die gesamte Funktionalität kapselt. Das ist natürlich keine sinnvolle Lösung, da eine Strukturierung der Lösung die Grundvoraussetzung für die Wartbarkeit einer Business- Anwendung ist. Es geht darum, die notwendige Strukturierung geeignet auszurichten und nicht darum, Strukturierung zu vermeiden.
Richtet man eine SOA – oder auch ein anderes strukturiertes, schnittstellenorientiertes System – an den Dynamics of Change aus, erhält man ein System, das bestmöglich für die Wartung und Weiter entwicklung aufgestellt ist. Dabei wird man häufig feststellen, dass dies nicht die gleiche Struktur hat wie die, die man erhält, wenn man nur die Entwicklung des Systems betrachtet. Hierin liegt auch eines der größten Probleme im Design for Maintenance. In einem typischen Softwareentwick lungsprojekt, das seine Ergebnisse zeitbudget- und qualitätsgerecht abzuliefern hat, ist das Design strikt an den Projekterfordernissen ausgerichtet. Damit stehen Entwicklungskriterien im Fokus und keine Wartungskriterien.
SOA hat in diesem Kontext gegenüber den früheren Ansätzen einen Vorteil: SOA wird als langfristiges, projektübergreifendes Unterfangen verstanden, das auch eine übergreifende Steuerung und Kontrolle jenseits einzelner Projekte benötigt (Stichwort „SOA-Governance”). Damit hat man erstmals die Möglichkeit, dieses Problem mit den (erweiterten) Mitteln des Konzepts zu lösen.
Tipps für die Praxis
Es bleibt die Frage, wie sich Design for Maintenance in der Praxis umsetzen lässt. Diese berechtigte Frage lässt sich nicht pauschal beantworten. Jedes System und jedes Projekt ist in gewissem Maße einzigartig, was Anforderungen, Rahmenbedingungen, Stakeholder, Budget usw. betrifft. Daher lässt sich auch kein allgemein gültiges Vorgehen definieren, wie man ein gutes Design for Maintenance erhält. Trotzdem gibt es ein paar allgemeine Tipps, die zumindest mir bei meiner Tätigkeit gute Dienste geleistet haben. Die meisten dieser Hinweise sind nicht wirklich neu. Dennoch ist es immer wieder erstaunlich zu beobachten, wie häufig diese Hinweise in der täglichen Arbeit übersehen werden.
Business first
Der wichtigste Treiber für eine gute Architektur moderner Unternehmensanwen dungen ist ein profundes Verständnis der fachlichen Anforderungen und der zugehörigen Domäne. In der Praxis kommen erfahrungsgemäß etwa 90 % aller Änderungsanforderungen aus der Fachlichkeit. Technologisch gibt es typischerweise alle paar Jahre einen Upgrade auf eine neue Version einer Infrastrukturkomponente (Datenbank, Anwendungs - server, Framework usw.), aber in der Summe bleibt die Technik vergleichsweise stabil.
Im Gegensatz dazu ändern sich die fachlichen Anforderungen ständig. Daher ist es essenziell, die Fachlichkeit möglichst gut zu durchdringen, um eine Lösung gestalten zu können, die in der Lage ist, mit den Dynamics of Change umzugehen.
Anforderungen beobachten
Wenn man als Architekt die Möglichkeit hat, die Entwicklung und die Veränderung der Anforderungen über die Zeit zu beobachten, ist das eine wertvolle Informationsquelle. Unpräzise oder sehr generische Anforderungen sind z. B. ein Indikator für schwerpunkt eine Stelle, an der Änderungen zu erwarten sind.
Hat man Zugriff auf die wichtigsten Business-Features, die in den vergangenen ein oder zwei Jahren im Kontext der aktuellen Domäne angefordert wurden, ist das ebenfalls ein guter Indikator. Darüber hinaus sollte man Informationsquellen wie die Geschäftsstrategie, die IT-Strategie, gesetzliche Änderungen usw. nutzen, wenn sie zur Verfügung stehen.
Auch hier gilt wie beim vorherigen Punkt, dass die Fachlichkeit normalerweise die treibende Kraft für Änderungen ist. Technologisch bleiben die meisten ITSysteme über ihren Lebenszyklus sehr stabil. Stehen größere IT-getriebene Änderungen an, wird das System eher neu implementiert, als dass das bestehende System geändert wird. Alternativ findet z. B. im Kontext von EAI oder SOA ein Wrapping der vorhandenen Systeme statt. Aber auch in dem Fall bleibt die Technologie der bestehenden Systeme stabil.
Bei loser Kopplung die Fachebene nicht vergessen
Lose Kopplung ist für wartbare Systeme wichtig. Gerade bei SOA, aber auch bei CBD, gibt es viele Empfehlungen zum Thema „lose Kopplung”. Leider legen die meisten dieser Empfehlungen den Schwerpunkt in erster Linie auf technische Lösungsdetails, wie z. B. Lookup und Binding oder den Umgang mit Transaktionen. Das Problem ist, dass die beste technische Entkopplung nichts nützt, wenn die Schnittstelle auf der fachlichen Ebene eine enge Kopplung vorgibt.
Häufig entstehen solche engen Kopplungen im Rahmen eines implementierungsgetriebenen Designs auf Basis der folgenden Argumentation: Um die Nutzung und Wiederverwendbarkeit des Services nicht zu beschränken, wird eine möglichst allgemeine Schnittstelle exponiert. Als Folge werden dann häufig Implementierungsdetails – wie z. B. interne Datenstrukturen oder Konstanten – über die Schnittstelle preisgegeben.
Besonders häufig trifft man solche engen inhaltlichen Kopplungen im Rahmen von Bottom-Up-Ansätzen, bei denen vorhandene Implementierungen nachträglich als Services exponiert werden. Mit einer solchen engen inhaltlichen Kopplung ist eine Änderung der Implementierung des Services nur noch möglich, wenn man alle Nutzer auch anpasst, was die Wartbarkeit des Systems stark einschränkt.
Daher ist es wichtig, schon bei der Definition der Schnittstellen auf fachlicher Ebene auf eine strikte Entkopplung von der Implementierung zu achten und unabhängig von eventuell bestehenden Implementierungen auf eine saubere Trennung der Verantwortlichkeiten (Separation of Concerns) zu achten. Dafür muss man sich zwar ab und zu (teilweise hitziger) Anschuldigungen erwehren, unnötigen Overhead und nicht performante Lösungen zu erzeugen. Die Nerven, die man in solche Diskussionen investiert, zahlen sich aber erfahrungsgemäß später vielfach aus.
Fachlichkeit und Technologie entkoppeln
Auch wenn ich weiter oben geschrieben habe, dass sich die technischen Aspekte eines Systems erfahrungsgemäß eher selten ändern, ist es doch sinnvoll, die fachlichen und technischen Bausteine eines Systems möglichst zu entkoppeln. Der Grund dafür ist eine deutlich erhöhte Wartbarkeit. Es ist deutlich einfacher, eine fachliche Änderung umzusetzen, wenn der betroffene Code nicht zwischen Unmengen technischer Aspekte gesucht werden muss.
Das mag trivial klingen, summiert sich in der täglichen Wartungs- und Änderungspraxis aber zu einem erheblichen Kostenund Fehlerfaktor auf. Anregungen zur Trennung von Fachlichkeit und Technologie findet man z. B. in [Sie04].
Abb. 4: In der Praxis beschreiben die "Dynamics of Change" die am häufigsten auftretenden Änderungsanforderungen.
Vorsicht bei der Schichtenarchitektur
Wie bereits erwähnt, ist die Schichtenarchitektur ein technisch motiviertes Strukturierungsprinzip für Anwendungen, das es einem ermöglicht, technische Belange voneinander zu entkoppeln. Das ist während der Erstentwicklung für die Planung der technischen Experten hilfreich, in der Wartung und Weiterentwicklung dominieren aber fachliche Änderungsanforderungen, die häufig quer zur Schichtenarchitektur stehen.
Ist die Schichtenarchitektur deshalb grundsätzlich schlecht? Aus meiner Sicht lässt sich diese Frage nicht pauschal beantworten, aber es gibt einige Aspekte, die in diesem Zusammenhang zu beachten sind: Zunächst einmal reicht es nicht aus, eine Schichtenarchitektur als alleiniges Strukturierungsmittel für eine Anwendungsarchitektur zu nutzen. Um überhaupt eine Chance zu haben, mit einer Vielzahl von fachlichen Änderungsanforderungen umgehen zu können, muss die Facharchitektur die dominante Architektur sein. „Dominant” bedeutet in diesem Zusammenhang, dass sie die oberste Struk turierungsebene darstellt und so die verschiedenen fachlichen Bausteine von einander entkoppelt. Innerhalb eines fachlichen Bausteins kann eine Strukturierung nach Schichten das angemessene Mittel sein, zumindest zur Entkopplung der technischen Domänen.
Insgesamt ist – wie bei vielen anderen Prinzipien auch – bei der Schichtenarchitektur Augenmaß gefragt. Obwohl die Schichtenarchitektur bis heute als das klassische Strukturierungsmittel von Anwendungen angesehen wird, sollte man eine neue Anwendungsarchitektur nicht mit dem Definieren der Schichten beginnen, sondern erst einmal darüber nachdenken, welche Strukturierung des Systems den Dynamics of Change am besten Rechnung trägt.
Vorsicht bei generischen Lösungen Generische Lösungen werden häufig als eine Art universelle Antwort auf alle Probleme mit Änderungsanforderungen ins Feld geführt: Ist die Lösung nur generisch genug, können damit alle zukünftigen Änderungsanforderungen ohne Implementierungsaufwand umgesetzt werden. An der Stelle muss aber klar unterschieden werden, ob die generische Lösung die Antwort auf einen benötigten Variabilitätsgrad der Fachdomäne darstellt oder in Wirklichkeit nur eine Ersatzlösung für eine nicht gut genug durchdrungene Fachdomäne ist.
Das Problem generischer Lösungen ist nämlich, dass sie einen zusätzlichen Komplexitätsgrad in die Software einführen. Damit ist das System schwerer zu verstehen und in Folge schwerer zu warten. Wählt man eine generische Lösung aus den falschen Gründen, d. h. aufgrund einer nicht gut genug durchdrungenen fachlichen Domäne, erhält man im Ergebnis eine schlechter wartbare und änderbare Lösung und muss die fehlende Fachlogik letztlich doch nachprogrammieren – zwar nicht im Quellcode, aber in Form von oftmals komplexen Konfigurationen. Das bedeutet nicht, dass generische Lösungen per se schlecht sind. An den richtigen Stellen eingesetzt helfen sie, sich häufig ändernde Stellen der Fachdomäne in der ITLösung mit der benötigten Flexibilität und Änderungsfreundlichkeit zu versehen. Falsch eingesetzt erhält man aber nur ein schlechter verständliches und wartbares System – und häufig zusätzlich einen Performance-Killer.
Architektur regelmäßig überprüfen Es ist wichtig zu verstehen, dass eine Architektur kein statisches Gebilde ist, sondern etwas Dynamisches, das sich über die Zeit mit den Anforderungen ändern kann bzw. geändert werden muss. Anforderungen ändern sich über die Zeit und auch die Dynamics of Change können sich über die Zeit ändern. Daher ist es sinnvoll, von Zeit zu Zeit zu prüfen, ob die bestehende Architektur eigentlich noch geeignet ist, die zu erwartenden Änderungsanforderungen möglichst gut zu bedienen.
Ein gutes Mittel zur Überprüfung der Architektur sind – je nach benötigtem Umfang – z. B. „ATAM” und „SAAM” (vgl. [Cle01]). Hierbei handelt es sich um zwei Workshop-basierte Methoden. In den Workshops wird mit einem strukturierten Vorgehen anhand von Szenarien analysiert, wie gut die Architektur geeignet ist, mit bestimmten Arten von Änderungen umzugehen. Bei der Definition der Szenarien muss man darauf achten, dass sie zu den am häufigsten zu erwartenden Änderungsanforderungen passen.
Es gibt natürlich auch andere Möglichkeiten, eine Architektur zu überprüfen. Wichtig ist nur, dass man es regelmäßig macht und eine Architektur nicht als etwas einmaliges, nach seiner initialen Definition dauerhaft Erledigtes ansieht.
Zusammenfassung
Diese allgemeinen Tipps können beim Erstellen eines Design for Maintenance helfen. Die Liste ist natürlich nicht vollständig und garantiert auch kein perfektes Design. Aus meiner Erfahrung helfen sie aber dabei, sich auf die relevanten Aspekte zu konzentrieren.
Wiederverwendung ist eine hilfreiche und sinnvolle Maßnahme, um Kosten in der Softwareentwicklung zu senken und die Qualität zu steigern. Nur ist sie das Ergebnis eines langen Entwicklungsprozesses in einem Unternehmen und sollte auch so verstanden werden. Außerdem gibt es – insbesondere auf der Geschäftsseite – begründete Einschränkungen bezüglich der Wiederverwendbarkeit großer, fachlicher Bausteine.
Da außerdem die Einsparpotenziale in der Softwareentwicklung wesentlich geringer sind als in der Wartung und Weiterentwicklung, sollte Re-Use als nachgelagerter Optimierungsschritt verstanden wer den, der nach Erschließung der Potenziale im Bereich Wartung und Weiterentwicklung angegangen wird. Statt eines Design for Re-Use ist ein Design for Maintenance anzustreben, in dem die Bausteine zugunsten der Minimierung der Kosten für die Dynamics of Change geschnitten werden.
Für die Umsetzung gibt es, wie so oft, kein Patentrezept. Wenn man aber Architektur und Design unter Berücksichtigung dieses Wissens betreibt, erhält man in der Regel eine andere Struktur der Software und ist damit schon einen großen Schritt weiter auf dem Weg zu flexiblen und nachhaltigen Architekturen.
Literatur & Links
[Bro95] F.P. Brooks, The Mythical Man Month: Essays on Software Engineering (Spec. Ed.), Addison-Wesley Longman, 1995
[Cle01] P. Clements, R. Kazman, M. Klein, Evaluating Software Architectures: Methods and Case Studies, Addison-Wesley Longman, 2001
[Jos09] N. Josuttis, Der wirkliche Business- Case von SOA, OOP 2009
[Kav97] D. Kavanagh, Improving O-O Software Re-Use Development using the Re-Use Maturity Model, OOP 1997
[Kos03] J. Koskinen, Software Maintenance Cost, 2003 (siehe: www.cs.jyu.fi/~koskinen/smcosts.htm)
[Pri97] E.V. Price, Organizational Culture and Behavioral Issues Affecting Software Re-Use, WISR 8, in: Proc. of 8th Workshop on Institutio nalizing Software Re-Use, 1997 (siehe: www.umcs.maine.edu/~ftp/wisr/wisr8/papers/price/price.html)
[SEI09] Software Engineering Institute der Carnegie Mellon University, Capability Maturity Model Integration, 2009, siehe www.sei.cmu.edu/cmmi/
[Sie04] J. Siedersleben, Moderne Software- Architektur: Umsichtig planen, robust bauen mit Quasar, dpunkt.verlag, 2004
Wiederverwendung: Versprechen und Realität
Voraussetzungen für erfolgreiche Wiederverwendung
Wartung: Die eigentliche Herausforderung
Design for Maintenance
Einschränkungen und Fallstricke
Tipps für die Praxis
Zusammenfassung
Literatur & Links
Wiederverwendung: Versprechen und Realität
Eines der großen Versprechen der serviceorientierten Architektur (SOA) sind mittelfristige massive Kosteneinsparungen durch einen hohen Grad der Wiederverwendung (Re-Use) von Services. Mit diesem Versprechen steht SOA in der Tradition z. B der objektorientierten Softwareentwicklung (Object Oriented Design, OOD) oder der komponentenorientierten Softwareentwicklung (Component Based Design, CBD): Durch die saubere Kapselung von Funktionalität lassen sich in unterschiedlichen Kontexten wiederverwendbare Bausteine – seien es Klassen, Komponenten oder Services – realisieren. Diese Funktionalität muss in zukünftigen Projekten nicht mehr neu entwickelt werden, wodurch sich mittelfristig die erhöhten Anfangsinvestitionen für die Einführung des neuen Paradigmas nicht nur amortisieren, sondern hohe Kosteneinsparungen entstehen.
Diese Re-Use-Argumentation hat man in den letzten Jahren in dieser oder leicht abgewandelten Varianten regelmäßig als wichtiges Argument für die Einführung einer SOA gehört und hört sie teilweise immer noch. Damit reiht sich SOA nahtlos in die Tradition aller Paradigmen zur modularen, schnittstellenorientierten Strukturierung von Softwaresystemen ein. Jedes dieser Paradigmen war und ist untrennbar mit der Re-Use-Argumentation verbunden. In der Vergangenheit stellte man nach einiger Zeit immer wieder ernüchtert fest, dass sich die Versprechen der massiven Wiederverwendung von Softwarebau steinen nicht erfüllt hatten. Die erhöhten Anfangsinvestitionen wurden getätigt, aber die versprochenen Amortisationseffekte traten nicht ein, was zu großer Skepsis gegenüber dem jeweiligen Paradigma – bis hin zur offenen Ablehnung – führte, insbesondere in den Reihen der Entscheider, die die erhöhten Investitionen im Vertrauen auf die versprochene, spätere Amortisation genehmigt hatten. Auch im Kontext von SOA mehren sich mittlerweile die kritischen Stimmen. Erfahrungen aus größeren SOA-Projekten führten zu der Erkenntnis, dass der Grad der Service-Wiederverwendung vernachlässigbar gering ist (vgl. z. B. [Jos09]). Die Geschichte droht sich also einmal mehr zu wiederholen.
Voraussetzungen für erfolgreiche Wiederverwendung
Was sind die Gründe dafür, dass Wiederverwendung nicht funktioniert? Auf diese Frage gibt es mehrere Antworten. Häufig wird fälschlicherweise angenommen, dass alleine die Verwendung eines Paradigmas, das die Kapselung von Verantwortlichkeiten in „Bausteinen” – seien es Module, Objekte, Komponenten oder Services – zum Inhalt hat, ein Garant für eine erfolgreiche Wiederverwendungskultur ist. Diese Annahme ist falsch. Der Einsatz eines Paradigmas, das eine Kapselung von Verantwortlichkeiten in Softwaremodulen bietet, ermöglicht die Wiederverwendung von Software zwar, garantiert diese aber in keinster Weise.
Befasst man sich genauer damit, welche weiteren Rahmenbedingungen für eine erfolgreiche Software-Wiederverwendung erfüllt sein müssen, stellt man fest, dass Wiederverwendung in erster Linie ein organisatorisches und unternehmens-soziologisches Thema ist.
In [Pri97] wird beispielsweise anschaulich dargelegt, dass eine entsprechende Unternehmensorganisation und zugehörige Unternehmenskultur Voraussetzung für eine gezielte und systematische Wiederverwendung von Software ist, wie sie für die Realisierung von Einsparpotenzialen benötigt wird. In [Kav97] werden diese Aussagen noch weiter präzisiert und es wird eine Wiederverwendungs-Reifegrad- Matrix (Re-Use-Maturity-Matrix) eingeführt.
In dieser Matrix werden Artefakte für eine gezielte Wiederverwendung in Beziehung zur Unternehmensorganisation und -kultur im Sinne des CMM(I) Levels (Capability Maturity Model Integration, vgl. [SEI09]) des Unternehmens gesetzt. Aus der aufgestellten Matrix lässt sich ablesen, dass eine Wiederverwendung von Services im Sinne einer SOA einen sehr hohen CMM(I)-Level voraussetzt, den die meisten Unternehmen inhaltlich nicht erfüllen dürften. Auch wenn CMM(I) mittlerweile vielfach eher kritisch gesehen wird, besteht dennoch ein direkter Zusammenhang zwischen der Unternehmensorganisation und -kultur und einer erfolgreichen möglichen Wiederverwendung.
Abbildung 1 ist eine verfeinerte und aktualisierte Darstellung der Re-Use- Maturity-Matrix in Form eines Re-Use- Maturity-Graphen. Neben der Organisations ebene des Unternehmens (rechte Achse) beeinflussen die Granularität des Bausteins (untere Achse) und seine Domänen zuordnung (obere Achse) den Grad der erreichbaren Wiederverwendung (Grad der Schraffierung) unter Berücksichtigung des Abstraktionsgrades des Bausteins (linke Achse). Exemplarisch sind zusätzlich einige typische Bausteine eingetragen. Es ist direkt zu sehen, dass z. B. ein Business-Service im Sinne einer SOA wesentlich schwieriger wiederzuverwenden ist als eine einfache Klassenbibliothek.
Es muss eine Organisation etabliert und finanziert werden, die über das reine Erreichen von Projektzielen (Zeit, Budget, Qualität) hinaus das Identifizieren, Konsolidieren, Verfeinern, Bereitstellen und Vermarkten von wiederverwendbaren Bausteinen unterstützt. Neben der reinen Identifikation und Bereitstellung von wiederverwendbaren Bausteinen sind hier insbesondere die Aufwände für das Konsolidieren und Verfeinern eines Bausteins zu berücksichtigen. Die Aufarbeitung eines Projektartefakts zu einem systematisch wiederverwendbaren Baustein entspricht inhaltlich der Aufarbeitung eines Projektartefakts zu einem Produkt, das extern verkauft werden soll.
Dazu sagt Fred Brooks: „Producing a product takes about 9 times as much effort as implementing its components individually for internal use (productization adds a factor of 3, integration and test adds a factor of 3)” (vgl. [Bro95]). Dieses kurze Zitat bringt zum Ausdruck, dass die Herstellung eines systematisch wiederverwendbaren Bausteins einen erheblich höheren Aufwand bedeutet als die reine Implementierung im Rahmen eines Projekts. Diese Mehraufwände können typischerweise nicht im Rahmen des den Baustein initial produzierenden Projekts erbracht werden, da dieses normalerweise weder über die Zeit noch über das Budget für die notwendige Überarbeitung verfügt.
Auf Ebene der Unternehmenskultur ist es notwendig, eine Abkehr vom verbreiteten NIH-Syndrom (Not Invented Here) zu etablieren. Dieses Syndrom besagt, dass insbesondere Softwareentwickler wesentlich lieber selbst eine neue – oftmals nur mittel mäßig gute – Lösung entwickeln, anstatt zu prüfen, ob es bereits vorhandene Lösungen gibt, die sie wiederverwenden können. Nebenbei müssen aufbereitete, wiederverwendbare Bausteine auch, wie zuvor beschrieben, im Unternehmen vermarktet werden, damit ein Entwickler darauf aufmerksam werden kann.
Neben dem grundsätzlichen, verbreiteten Misstrauen eines Softwareentwicklers gegenüber Code, den er nicht selbst entwickelt hat, unterstützt auch die Projektkultur dieses Vorgehen: Für einen Entwickler ist leichter absehbar und planbar, was es für ihn bedeutet, eine Funktionalität neu zu entwickeln, als die Integration einer vorhandenen, fremden Software. Insbesondere wenn die fremde Software nicht entsprechend zu einem wiederverwendbaren Produkt aufbereitet wurde, kann ein Softwareentwickler dem Projektleiter mit seinen Zeit- und Budget- Anforderungen besser Auskunft geben, wenn er die benötigte Funktionalität selber entwickelt. Letztlich hat die Wiederverwendung noch mit einem weiteren Problem zu kämpfen. Es ist wünschenswert, möglichst große, grob-granulare Bausteine (z. B. Services und Komponenten) wiederzuverwenden, damit der Effekt aus der Wiederverwendung möglichst hoch ist. Es gilt: Je größer und höherwertiger ein Baustein ist, desto mehr ist er bei sauberem Architekturentwurf an der zugehörigen Fachdomäne ausgerichtet. Eine Fachdomäne tendiert aber dazu, aufgrund der für heutige Wettbewerbsfähigkeit notwendigen Effizienz praktisch kaum noch Redundanzen aufzuweisen. Hat man also einen Baustein entwickelt, der ein domänenbezogenes Stück Fachlogik adäquat kapselt, wird dieser per se nicht wiederverwendet, weil er auch in der realen Welt nur an einer Stelle benötigt wird. Auch das ist ein Grund dafür, warum sich – zumindest bei guter Architektur – kleine und eher technisch orientierte Bausteine deutlich besser wiederverwenden lassen als große, fachlich orientierte Bausteine.
Wartung: Die eigentliche Herausforderung
Wenn ein Architekturkonzept wie SOA also nicht bzw. nur mit großen Zusatzaufwänden Wiederverwendung und die damit verbundenen Einsparpotenziale ermöglicht, stellt sich die Frage: Wofür das alles? Die versprochenen Einsparungen gibt es nicht bzw. nur mit großem Aufwand in ferner Zukunft. Haben wir es hier nur mit einer Schrulle strukturverliebter Architekten zu tun oder worin liegt der Nutzen schnittstellenbasierter Kapselung? Die einfache Antwort ist: Eine schnittstellenbasierte Kapselung von Verantwortlichkeiten bringt sehr viel, nur lenkt die Re- Use-Argumentation den Blick in die falsche Richtung. Der Nutzen entsteht nämlich nicht in der Entwicklung einer Funktionalität (Construction), sondern in der Wartung (Maintenance). Unter Wartung ist nicht nur das Beheben von Fehlern zu verstehen, sondern auch die Weiterentwicklung der Software, d. h. die Anpassung an neue fachliche und technische Anforderungen. Betrachtet man die Ergebnisse entsprechender Studien, wie sie z. B. in [Kos03] anschaulich zusammengefasst sind, stellt man fest, dass heutzutage zwischen 70 % und 90 % der IT-Budgets für die Wartung und Weiterentwicklung von Software aufgewendet wird – Tendenz steigend. Anders ausgedrückt: Nur 10 % bis 30 % der ITBudgets gehen in die Entwicklung neuer Software, während der große Rest in die Pflege bestehender Software investiert wird (siehe auch Abb. 2).
Dieses Verhältnis verdeutlicht, dass die größten Kostenfallen und damit auch die größten Einsparpotenziale der Softwareentwicklung nicht in der Neuentwicklung von Funktionalität, sondern in der Pflege und Weiterentwicklung liegen. Wenn man es schafft, die Software so zu konzipieren und zu entwickeln, dass dieser Kostenblock kleiner wird, kann man damit echte Kosteneinsparungen erzielen.
Die Fokussierung auf die Kostensenkung in der Softwareentwicklung führt hingegen nur zu geringen Einspareffekten. Das ist eine der größten Fehlinterpretationen in der typischen Argumentation bezüglich der Software-Wiederverwendung: Das Ziel muss nicht Design for Re-Use, sondern Design for Maintenance sein.
Design for Maintenance
Was bedeutet das z. B. für eine SOA bzw. – im übertragenen Sinne – für in gewisser Weise vergleichbare Paradigmen wie CBD und OOD? Einfach ausgedrückt müssen Services so geschnitten werden, dass die Wartungsaufwände möglichst gering sind. Das klingt zunächst trivial, erweist sich in der Praxis aber als sehr schwierig. Wie erreicht man das?
Der Ansatz hierfür besteht darin, die Änderungsanforderungen zu beobachten und die Struktur der Software an den am häufigsten auftretenden Änderungsanforderungen, den Dynamics of Change, auszurichten. Üblicherweise richtet sich die Struk turierung einer Software an Kriterien aus, die eine möglichst effiziente Entwicklung erlauben. Diese Strukturen ermöglichen aber nicht zwangsläufig eine möglichst effiziente Pflege. Das bedeutet:
Ein kleines Beispiel zur Erläuterung, das wahrscheinlich jeder von uns aus eigener Erfahrung kennt: Schichtenarchitekturen sind in den heutigen Softwaresystemen omnipräsent. Systeme werden in mehrere Schichten untergliedert, wie z. B. „Präsen tation”, „Geschäftslogik” und „Persistenz” (häufig sind es noch mehr). Über alle Schichten hinweg werden Datenstrukturen im Rahmen der verschiedenen Operationen transportiert und an den Schich - tengrenzen zugunsten einer Entkopp lung der Schichten voneinander auch transformiert.
Diese Architektur ist für die Entwicklung eines Systems gut geeignet. Einzelne Entwicklungsteams mit dem entsprechenden Spezialwissen, z. B. für GUI-Entwicklung, RDBMS-Zugriff oder Adapter- Programmierung, können die einzelnen Bausteine weitestgehend unabhängig voneinander entwickeln, womit sich die vorhandenen Entwicklerkapazitäten recht zielgenau planen und einsetzen lassen.
Sind die typischen Anforderungen für ein solches in Schichten strukturiertes System allerdings Änderungen an den Datenstrukturen, getrieben durch entsprechende fachliche Anforderungen, ist die Schichtenarchitektur eher kontraproduktiv. Für jede Datenstruktur-Änderungsanforderung muss eine ganze Reihe Bausteine geändert werden, Schnittstellen werden geändert, die Änderungen sind nicht-lokal. Die für die Entwicklung gut geeignete Schichtenarchitektur erweist sich in dem Beispiel aufgrund der Art der Änderungsanforderungen als nicht gut geeignet1).
An diesem einfachen Beispiel wird klar, dass eine für die Softwareentwicklung gute Struktur nicht unbedingt eine gute Struktur für deren Pflege ist. Um eine für die Pflege gute Strukturierung zu erhalten, muss man die Dynamics of Change betrachten.
Aber wie identifiziert man zukünftige Änderungsanforderungen? In der Regel kennt man sie nicht und betrachtet daher üblicherweise die Anforderungen der Vergangenheit in der Erwartung, dass vergleichbare Anforderungen auch in Zukunft gestellt werden. (In den „Tipps für die Praxis” weiter unten im Artikel finden sich noch Empfehlungen für weitere Indikatoren für zukünftige Änderungsanforderungen.)
Diese Änderungsanforderungen sind dann bezüglich ihrer Auswirkungen auf die IT-Systeme zu bewerten. Bedeuten sie am ehesten Änderungen an Daten, an Funktionen oder an Prozessen? Wie muss ich meine Software und meine Services schneiden, damit die Änderungen möglichst lokal bleiben, also so, dass ich die Änderungen innerhalb eines Service möglichst oft ohne Änderung der Service-Schnittstelle umsetzen kann?
Die Auseinandersetzung mit diesen Fragen führt in letzter Konsequenz zu einer Veränderung des Architektur entwurfs: Normalerweise erfolgt dieser statisch, d. h. die bekannten Anforderungen werden analysiert und dafür wird eine geeignete Lösungsarchitektur entworfen. Eine solche Vorgehensweise ermöglicht eine gewisse Breite an Lösungsarchitekturen, wobei in der Regel diejenige Lösung gewählt wird, die die Erstellung der Software am besten unterstützt. Oft führt ein solcher Entwurf aber zu einer bezüglich den Änderungsanforderungen ungünstigen Architektur (siehe Abb. 3, oberer Teil).
Die zusätzliche Berücksichtigung der zu erwartenden Änderungsanforderungen über die Zeit führt zu einem dynamischeren Architekturentwurf. Bei diesem wird der Fokus nicht mehr primär auf die Erstellung der Software gelegt, sondern auf ihre Veränderung über die Zeit. In diesem Fall wird eine Lösungsarchitektur gewählt, die die Dynamics of Change, also die Änderungen der Software über die Zeit, möglichst optimal unterstützt (siehe Abb. 3 unterer Teil).
Einschränkungen und Fallstricke
Die Dynamics of Change beschreiben die am häufigsten auftretenden Änderungsanforderungen. Es ist nicht möglich, allen Änderungsanforderungen optimal gerecht zu werden, da manche Anforderungen – isoliert umgesetzt – zu sich gegenseitig widersprechenden Strukturierungen führen. Es gibt also nicht die optimale Struktur für alle Anforderungen, sondern nur eine Struktur, die die Dynamics of Change möglichst gut unterstützt (siehe Abb. 4).
Eine weitere Einschränkung bezieht sich auf die Analyse der Änderungsanforderungen und deren Auswirkungen auf die ITSysteme. Wendet man das Prinzip konsequent an, dass alle Änderungen lokal bleiben sollen und keine Schnittstellen verändert werden, führt das zwangsläufig zu einem großen Service, der die gesamte Funktionalität kapselt. Das ist natürlich keine sinnvolle Lösung, da eine Strukturierung der Lösung die Grundvoraussetzung für die Wartbarkeit einer Business- Anwendung ist. Es geht darum, die notwendige Strukturierung geeignet auszurichten und nicht darum, Strukturierung zu vermeiden.
Richtet man eine SOA – oder auch ein anderes strukturiertes, schnittstellenorientiertes System – an den Dynamics of Change aus, erhält man ein System, das bestmöglich für die Wartung und Weiter entwicklung aufgestellt ist. Dabei wird man häufig feststellen, dass dies nicht die gleiche Struktur hat wie die, die man erhält, wenn man nur die Entwicklung des Systems betrachtet. Hierin liegt auch eines der größten Probleme im Design for Maintenance. In einem typischen Softwareentwick lungsprojekt, das seine Ergebnisse zeitbudget- und qualitätsgerecht abzuliefern hat, ist das Design strikt an den Projekterfordernissen ausgerichtet. Damit stehen Entwicklungskriterien im Fokus und keine Wartungskriterien.
SOA hat in diesem Kontext gegenüber den früheren Ansätzen einen Vorteil: SOA wird als langfristiges, projektübergreifendes Unterfangen verstanden, das auch eine übergreifende Steuerung und Kontrolle jenseits einzelner Projekte benötigt (Stichwort „SOA-Governance”). Damit hat man erstmals die Möglichkeit, dieses Problem mit den (erweiterten) Mitteln des Konzepts zu lösen.
Tipps für die Praxis
Es bleibt die Frage, wie sich Design for Maintenance in der Praxis umsetzen lässt. Diese berechtigte Frage lässt sich nicht pauschal beantworten. Jedes System und jedes Projekt ist in gewissem Maße einzigartig, was Anforderungen, Rahmenbedingungen, Stakeholder, Budget usw. betrifft. Daher lässt sich auch kein allgemein gültiges Vorgehen definieren, wie man ein gutes Design for Maintenance erhält. Trotzdem gibt es ein paar allgemeine Tipps, die zumindest mir bei meiner Tätigkeit gute Dienste geleistet haben. Die meisten dieser Hinweise sind nicht wirklich neu. Dennoch ist es immer wieder erstaunlich zu beobachten, wie häufig diese Hinweise in der täglichen Arbeit übersehen werden.
Business first
Der wichtigste Treiber für eine gute Architektur moderner Unternehmensanwen dungen ist ein profundes Verständnis der fachlichen Anforderungen und der zugehörigen Domäne. In der Praxis kommen erfahrungsgemäß etwa 90 % aller Änderungsanforderungen aus der Fachlichkeit. Technologisch gibt es typischerweise alle paar Jahre einen Upgrade auf eine neue Version einer Infrastrukturkomponente (Datenbank, Anwendungs - server, Framework usw.), aber in der Summe bleibt die Technik vergleichsweise stabil.
Im Gegensatz dazu ändern sich die fachlichen Anforderungen ständig. Daher ist es essenziell, die Fachlichkeit möglichst gut zu durchdringen, um eine Lösung gestalten zu können, die in der Lage ist, mit den Dynamics of Change umzugehen.
Anforderungen beobachten
Wenn man als Architekt die Möglichkeit hat, die Entwicklung und die Veränderung der Anforderungen über die Zeit zu beobachten, ist das eine wertvolle Informationsquelle. Unpräzise oder sehr generische Anforderungen sind z. B. ein Indikator für schwerpunkt eine Stelle, an der Änderungen zu erwarten sind.
Hat man Zugriff auf die wichtigsten Business-Features, die in den vergangenen ein oder zwei Jahren im Kontext der aktuellen Domäne angefordert wurden, ist das ebenfalls ein guter Indikator. Darüber hinaus sollte man Informationsquellen wie die Geschäftsstrategie, die IT-Strategie, gesetzliche Änderungen usw. nutzen, wenn sie zur Verfügung stehen.
Auch hier gilt wie beim vorherigen Punkt, dass die Fachlichkeit normalerweise die treibende Kraft für Änderungen ist. Technologisch bleiben die meisten ITSysteme über ihren Lebenszyklus sehr stabil. Stehen größere IT-getriebene Änderungen an, wird das System eher neu implementiert, als dass das bestehende System geändert wird. Alternativ findet z. B. im Kontext von EAI oder SOA ein Wrapping der vorhandenen Systeme statt. Aber auch in dem Fall bleibt die Technologie der bestehenden Systeme stabil.
Bei loser Kopplung die Fachebene nicht vergessen
Lose Kopplung ist für wartbare Systeme wichtig. Gerade bei SOA, aber auch bei CBD, gibt es viele Empfehlungen zum Thema „lose Kopplung”. Leider legen die meisten dieser Empfehlungen den Schwerpunkt in erster Linie auf technische Lösungsdetails, wie z. B. Lookup und Binding oder den Umgang mit Transaktionen. Das Problem ist, dass die beste technische Entkopplung nichts nützt, wenn die Schnittstelle auf der fachlichen Ebene eine enge Kopplung vorgibt.
Häufig entstehen solche engen Kopplungen im Rahmen eines implementierungsgetriebenen Designs auf Basis der folgenden Argumentation: Um die Nutzung und Wiederverwendbarkeit des Services nicht zu beschränken, wird eine möglichst allgemeine Schnittstelle exponiert. Als Folge werden dann häufig Implementierungsdetails – wie z. B. interne Datenstrukturen oder Konstanten – über die Schnittstelle preisgegeben.
Besonders häufig trifft man solche engen inhaltlichen Kopplungen im Rahmen von Bottom-Up-Ansätzen, bei denen vorhandene Implementierungen nachträglich als Services exponiert werden. Mit einer solchen engen inhaltlichen Kopplung ist eine Änderung der Implementierung des Services nur noch möglich, wenn man alle Nutzer auch anpasst, was die Wartbarkeit des Systems stark einschränkt.
Daher ist es wichtig, schon bei der Definition der Schnittstellen auf fachlicher Ebene auf eine strikte Entkopplung von der Implementierung zu achten und unabhängig von eventuell bestehenden Implementierungen auf eine saubere Trennung der Verantwortlichkeiten (Separation of Concerns) zu achten. Dafür muss man sich zwar ab und zu (teilweise hitziger) Anschuldigungen erwehren, unnötigen Overhead und nicht performante Lösungen zu erzeugen. Die Nerven, die man in solche Diskussionen investiert, zahlen sich aber erfahrungsgemäß später vielfach aus.
Fachlichkeit und Technologie entkoppeln
Auch wenn ich weiter oben geschrieben habe, dass sich die technischen Aspekte eines Systems erfahrungsgemäß eher selten ändern, ist es doch sinnvoll, die fachlichen und technischen Bausteine eines Systems möglichst zu entkoppeln. Der Grund dafür ist eine deutlich erhöhte Wartbarkeit. Es ist deutlich einfacher, eine fachliche Änderung umzusetzen, wenn der betroffene Code nicht zwischen Unmengen technischer Aspekte gesucht werden muss.
Das mag trivial klingen, summiert sich in der täglichen Wartungs- und Änderungspraxis aber zu einem erheblichen Kostenund Fehlerfaktor auf. Anregungen zur Trennung von Fachlichkeit und Technologie findet man z. B. in [Sie04].
Abb. 4: In der Praxis beschreiben die "Dynamics of Change" die am häufigsten auftretenden Änderungsanforderungen.
Vorsicht bei der Schichtenarchitektur
Wie bereits erwähnt, ist die Schichtenarchitektur ein technisch motiviertes Strukturierungsprinzip für Anwendungen, das es einem ermöglicht, technische Belange voneinander zu entkoppeln. Das ist während der Erstentwicklung für die Planung der technischen Experten hilfreich, in der Wartung und Weiterentwicklung dominieren aber fachliche Änderungsanforderungen, die häufig quer zur Schichtenarchitektur stehen.
Ist die Schichtenarchitektur deshalb grundsätzlich schlecht? Aus meiner Sicht lässt sich diese Frage nicht pauschal beantworten, aber es gibt einige Aspekte, die in diesem Zusammenhang zu beachten sind: Zunächst einmal reicht es nicht aus, eine Schichtenarchitektur als alleiniges Strukturierungsmittel für eine Anwendungsarchitektur zu nutzen. Um überhaupt eine Chance zu haben, mit einer Vielzahl von fachlichen Änderungsanforderungen umgehen zu können, muss die Facharchitektur die dominante Architektur sein. „Dominant” bedeutet in diesem Zusammenhang, dass sie die oberste Struk turierungsebene darstellt und so die verschiedenen fachlichen Bausteine von einander entkoppelt. Innerhalb eines fachlichen Bausteins kann eine Strukturierung nach Schichten das angemessene Mittel sein, zumindest zur Entkopplung der technischen Domänen.
Insgesamt ist – wie bei vielen anderen Prinzipien auch – bei der Schichtenarchitektur Augenmaß gefragt. Obwohl die Schichtenarchitektur bis heute als das klassische Strukturierungsmittel von Anwendungen angesehen wird, sollte man eine neue Anwendungsarchitektur nicht mit dem Definieren der Schichten beginnen, sondern erst einmal darüber nachdenken, welche Strukturierung des Systems den Dynamics of Change am besten Rechnung trägt.
Vorsicht bei generischen Lösungen Generische Lösungen werden häufig als eine Art universelle Antwort auf alle Probleme mit Änderungsanforderungen ins Feld geführt: Ist die Lösung nur generisch genug, können damit alle zukünftigen Änderungsanforderungen ohne Implementierungsaufwand umgesetzt werden. An der Stelle muss aber klar unterschieden werden, ob die generische Lösung die Antwort auf einen benötigten Variabilitätsgrad der Fachdomäne darstellt oder in Wirklichkeit nur eine Ersatzlösung für eine nicht gut genug durchdrungene Fachdomäne ist.
Das Problem generischer Lösungen ist nämlich, dass sie einen zusätzlichen Komplexitätsgrad in die Software einführen. Damit ist das System schwerer zu verstehen und in Folge schwerer zu warten. Wählt man eine generische Lösung aus den falschen Gründen, d. h. aufgrund einer nicht gut genug durchdrungenen fachlichen Domäne, erhält man im Ergebnis eine schlechter wartbare und änderbare Lösung und muss die fehlende Fachlogik letztlich doch nachprogrammieren – zwar nicht im Quellcode, aber in Form von oftmals komplexen Konfigurationen. Das bedeutet nicht, dass generische Lösungen per se schlecht sind. An den richtigen Stellen eingesetzt helfen sie, sich häufig ändernde Stellen der Fachdomäne in der ITLösung mit der benötigten Flexibilität und Änderungsfreundlichkeit zu versehen. Falsch eingesetzt erhält man aber nur ein schlechter verständliches und wartbares System – und häufig zusätzlich einen Performance-Killer.
Architektur regelmäßig überprüfen Es ist wichtig zu verstehen, dass eine Architektur kein statisches Gebilde ist, sondern etwas Dynamisches, das sich über die Zeit mit den Anforderungen ändern kann bzw. geändert werden muss. Anforderungen ändern sich über die Zeit und auch die Dynamics of Change können sich über die Zeit ändern. Daher ist es sinnvoll, von Zeit zu Zeit zu prüfen, ob die bestehende Architektur eigentlich noch geeignet ist, die zu erwartenden Änderungsanforderungen möglichst gut zu bedienen.
Ein gutes Mittel zur Überprüfung der Architektur sind – je nach benötigtem Umfang – z. B. „ATAM” und „SAAM” (vgl. [Cle01]). Hierbei handelt es sich um zwei Workshop-basierte Methoden. In den Workshops wird mit einem strukturierten Vorgehen anhand von Szenarien analysiert, wie gut die Architektur geeignet ist, mit bestimmten Arten von Änderungen umzugehen. Bei der Definition der Szenarien muss man darauf achten, dass sie zu den am häufigsten zu erwartenden Änderungsanforderungen passen.
Es gibt natürlich auch andere Möglichkeiten, eine Architektur zu überprüfen. Wichtig ist nur, dass man es regelmäßig macht und eine Architektur nicht als etwas einmaliges, nach seiner initialen Definition dauerhaft Erledigtes ansieht.
Zusammenfassung
Diese allgemeinen Tipps können beim Erstellen eines Design for Maintenance helfen. Die Liste ist natürlich nicht vollständig und garantiert auch kein perfektes Design. Aus meiner Erfahrung helfen sie aber dabei, sich auf die relevanten Aspekte zu konzentrieren.
Wiederverwendung ist eine hilfreiche und sinnvolle Maßnahme, um Kosten in der Softwareentwicklung zu senken und die Qualität zu steigern. Nur ist sie das Ergebnis eines langen Entwicklungsprozesses in einem Unternehmen und sollte auch so verstanden werden. Außerdem gibt es – insbesondere auf der Geschäftsseite – begründete Einschränkungen bezüglich der Wiederverwendbarkeit großer, fachlicher Bausteine.
Da außerdem die Einsparpotenziale in der Softwareentwicklung wesentlich geringer sind als in der Wartung und Weiterentwicklung, sollte Re-Use als nachgelagerter Optimierungsschritt verstanden wer den, der nach Erschließung der Potenziale im Bereich Wartung und Weiterentwicklung angegangen wird. Statt eines Design for Re-Use ist ein Design for Maintenance anzustreben, in dem die Bausteine zugunsten der Minimierung der Kosten für die Dynamics of Change geschnitten werden.
Für die Umsetzung gibt es, wie so oft, kein Patentrezept. Wenn man aber Architektur und Design unter Berücksichtigung dieses Wissens betreibt, erhält man in der Regel eine andere Struktur der Software und ist damit schon einen großen Schritt weiter auf dem Weg zu flexiblen und nachhaltigen Architekturen.
Literatur & Links
[Bro95] F.P. Brooks, The Mythical Man Month: Essays on Software Engineering (Spec. Ed.), Addison-Wesley Longman, 1995
[Cle01] P. Clements, R. Kazman, M. Klein, Evaluating Software Architectures: Methods and Case Studies, Addison-Wesley Longman, 2001
[Jos09] N. Josuttis, Der wirkliche Business- Case von SOA, OOP 2009
[Kav97] D. Kavanagh, Improving O-O Software Re-Use Development using the Re-Use Maturity Model, OOP 1997
[Kos03] J. Koskinen, Software Maintenance Cost, 2003 (siehe: www.cs.jyu.fi/~koskinen/smcosts.htm)
[Pri97] E.V. Price, Organizational Culture and Behavioral Issues Affecting Software Re-Use, WISR 8, in: Proc. of 8th Workshop on Institutio nalizing Software Re-Use, 1997 (siehe: www.umcs.maine.edu/~ftp/wisr/wisr8/papers/price/price.html)
[SEI09] Software Engineering Institute der Carnegie Mellon University, Capability Maturity Model Integration, 2009, siehe www.sei.cmu.edu/cmmi/
[Sie04] J. Siedersleben, Moderne Software- Architektur: Umsichtig planen, robust bauen mit Quasar, dpunkt.verlag, 2004