Agilität braucht nicht nur agile Teams, sondern auch eine flexible Softwarearchitektur.
„Die besten Architekturen, Anforderungen und Entwürfe entstehen durch selbstorganisierte Teams.“ So sieht es das agile Manifest vor.
Dieses 11. Prinzip1)hat zu den größten Missinterpretationen in der agilen Community geführt. Die agile Herangehensweise funktioniert am besten, wenn das Entwicklungsteam, zum Beispiel mit Scrum, die Infrastruktur und die Softwarearchitektur Stück für Stück, parallel zu den funktionalen Anforderungen, entwickelt. Im Idealfall wird der Aufwand für nicht funktionale Anforderungen von Sprint zu Sprint weniger und der funktionale Anteil bekommt mehr Raum. Es wird keine Architektur auf Vorrat gebaut, sondern immer nur der Aspekt, der gerade ansteht.
Dieses Prinzip setzt eine Basisarchitektur voraus, die dem Stand hält.
Eine Basisarchitektur wählen
Ein Softwareprodukt ist wie ein lebender Superorganismus, der zu einer passenden Klimazone gehört. Ein Korallenriff vor der Küste Australiens braucht eine bestimmte Temperatur und Wasserqualität. Schon kleinste Veränderungen im Umfeld führen dazu, dass ein Riff verödet.
Wichtig ist die frühe Entscheidung für das richtige Architekturprinzip. Eine kleine Anwendung auf dem PC braucht keine Vernetzung. Eine weltweit verteilte Anwendung kommt nicht ohne die Cloud aus. Eine Softwarelandschaft in der Cloud gleicht einem Korallenriff. Hardware, Software und Menschen leben in Symbiose.
Hier heißt es groß denken und klein handeln. Bei dem Start der Entwicklung eines neuen Produktes ist es notwendig, vorausschauend an die Sache ran zu gehen. Dies gilt genauso für ein Startup, wie für ein großes Unternehmen. Es geht nicht darum im Vorfeld viel Aufwand in die Architektur zu stecken, sondern einen geeigneten Weg zu wählen. Die Architektur wächst, wie ein Riff.
Die Plattformen auf denen Softwarearchitekturen gründen werden immer komplexer. Ständige Veränderung ist unvermeidlich. Kevin Kelly beschreibt dies in seinem Buch „The Inevitable“2)als „Werden“. Alles ist am Werden. Zusätzlich zu den Wünschen nach Neuerung der Kunden und Sponsoren gibt es auch die sich ständig verändernde digitale Landschaft um uns herum. Wir leben in einem Wettlauf aus Aktualisierungen. Jedes Softwareteam möchte so oft wie möglich ausliefern. Dies betrifft nicht nur Betriebssysteme, sondern auch alle Werkzeuge, die darauf aufbauen, mit. Dies ist eine einzige Co-Abhängigkeit.
Wenn diese nötigen Upgrades verzögert werden, dann wird die Sache noch riskanter. Am Ende erreicht der aufgestaute Superupgrade solche Ausmaße, dass kaum einer den Mut aufbringt, die nötigen Entscheidungen zu treffen. Dies mutet dann an wie ein sterbendes Ökosystem, das dann nur noch durch einen teuren Neuanfang ersetzt werden kann.
Die Lösung für dieses Problem ist eine ständig mitwachsende Architektur. Ständiges hegen und pflegen benötigt Zeit und Aufmerksamkeit. Die hundertprozentige Automatisierung für Builds, Upgrades und Deployments sind Voraussetzung. Das muss zuerst einmal eingerichtet und dann ständig nachgerüstet werden. Die ständige Veränderung muss auch der Architektur des Systems willkommen sein. Jede Verbesserung, egal auf welcher Ebene, bietet am Ende mehr Kundennutzen. Dieses Prinzip ist bei Scrum Teams als „Emergente Architektur“ bekannt.
Emergente Architekturen
Emergente Architekturen entstehen durch inkrementelles, iteratives Arbeiten. Diese Vorgehensweise kennt man in Scrum unter dem Begriff „Sprint“.
Die Idee solch einer Softwarearchitektur ist es, dass in jedem Sprint genau so viel Aufwand für Architektur investiert wird, dass das anvisierte „Sprint Goal“ erreicht werden kann. Diese Idee lässt sich nur in die Praxis umsetzen, wenn das zugrundeliegende Architekturprinzip stimmt. Ein Scrum Entwicklungsteam wendet in den ersten Sprints viel Zeit dafür auf, die Basisarchitektur zum Laufen zu bringen. Desto weiter das Team mit der Entwicklung voranschreitet, desto geringer wird der Aufwand für Infrastruktur- und Architekturaufgaben.
Symptome einer ungeeigneten Basisarchitektur
„Wir machen Scrum, deshalb liefern wir früh viele Features.“ Dies ist eine oft gehörte Interpretation, die leicht schiefgehen kann. In den ersten Sprints wird scheinbar viel ausgeliefert, um zu glänzen. Kunden und Auftraggeber werden beeindruckt. Agile Entwicklung bedeutet jedoch nicht, dass wir Prototypen bauen wollen, die wir am Ende wegwerfen. Nach mehreren Sprints gerät eine zu kurz gedachte Architektur in eine Sackgasse. Es werden dann mehrere Sprints für ein Refactoring benötigt oder im schlimmsten Fall muss neu begonnen werden.
Dafür bekommen die Teams in der Regel keine Zeit, weil das frühe Zeigen von Features hohe Erwartungen geweckt hat.
Dies wäre damit vergleichbar, wenn man in Nordeuropa ein Gewächshaus aufstellt und so demonstriert, dass hier Orangen wachsen können. Das reicht für einen kleinen Vorgeschmack. Wenn plötzlich eine ganze Plantage mit Orangen bestückt werden soll, dann bereitet das Probleme. Auf der Basis von Gewächshaustechnologie skaliert die Idee einfach nicht. Das Gewächshaus bietet zwar Kontrolle und Sicherheit, mehr als der erste Prototyp kann in solch einem Szenario jedoch nur mit viel zusätzlichen Aufwand gezeigt werden.
Eine gewählte Architektur soll sich frei weiter entwickeln können und nicht an technologischen Grenzen scheitern.
Grenzen, an die Architekturen stoßen, können verschiedene Ursachen haben. Beispiele hierfür gibt es viele. Skalierung auf viele Server, rund um den Globus, ist ein Wichtiges. Auch das Thema Sicherheit muss früh durchdacht sein. Wenn die Sicherheit eines Systems nur hinter der Firewall des heimischen Betriebs funktioniert, dann ist dieses nicht cloudfähig.
Vor allem der Umgang mit Altsystemen bedeutet eine Herausforderung, wenn diese agil weiterentwickelt werden sollen. Da muss dann für den Umbau in das alte System noch einmal kräftig investiert werden.
Entwicklerteams verantworten die Architektur
Das Team, das an einer Softwareplattform entwickelt, ist ein integraler Bestandteil dieser. Es haucht dem System das Leben ein. So wie das System sich verändert und wächst, steigt oder fällt der Grad der Lernkurve des Entwicklungsteams. Um es in den Worten von Kevin Kelly zu formulieren: „Endless Newbie“ ist das Normale für jeden, egal wie alt oder erfahren.
Da sich jeder Einzelne im Team auf diesen Lernprozess einlassen muss, ist es weder sinnvoll noch möglich dies an einen Systemarchitekten zu delegieren. Es ist die Aufgabe der Entwickler sich das Wissen anzueignen, zu teilen und sich den Konflikten zu stellen, die dieser schmerzhafte Dauerlernprozess mit sich bringt. Es wird Diskussionen im Team über die richtige strategische Richtung geben. Fehlentscheidungen gehören dazu. Wenn dies passiert, dann ist es wichtig, sich dies früh einzugestehen und den Kurs zu korrigieren. Hinterher ist man immer schlauer.
Cloud Architekturen
Business Agility bedeutet, dass Time-to-Market so kurz wie möglich ist. Scrum Teams wollen oft ausliefern, am liebsten täglich, spätestens jedoch nach jedem Sprint. Da kommen die neuen Services der Cloud Anbieter gerade recht. Microsoft, IBM, Google, Amazon und viele andere Anbieter bieten Plattformen, auf denen sich Teams selbst bedienen können. Hier können private Clouds, öffentliche Clouds oder eine Mischung aus beiden, bereitgestellt werden. Infrastruktur „as a Service“ und andere aaS stehen als Fertigprodukt zur Verfügung. So kann eine vernetzte Basisarchitektur entstehen, hoch verfügbar, schnell und skalierbar.
Diese neuen Angebote und Tools kommen der agilen Philosophie sehr entgegen, weil es das Konzept der autonomen Teams fördert. Die Verantwortung für den gesamten Lifecycle kann von diesem übernommen werden.
Teamkommunikation
Der US Informatiker Melvin Edward Conway beobachtete 1968 bereits Folgendes: „Organisationen, die Systeme entwerfen, sind auf Entwürfe festgelegt, welche die Kommunikationsstrukturen dieser Organisation abbilden“. Das Gesetz von Conway 3)adressiert die Tatsache, dass für die Definition von Schnittstellen zwischen getrennten Softwaremodulen zwischenmenschliche Kommunikation notwendig ist. So haben Kommunikationsstrukturen der Organisationen einen großen Einfluss auf die Strukturen der Schnittstellen. Wenn ein Team sich gemeinsam um ein Software-Modul kümmert, dann kann die Schnittstelle zu einem anderen Software-Modul gleichzeitig die menschliche Kommunikation zwischen den Teams repräsentieren und bedingen. Schnittstellen sind das Resultat der Kommunikation. Scrum Teams sind klein. Die Kommunikation zwischen ihnen sollte von Angesicht zu Angesicht stattfinden.
Zusätzlich müssen die Schnittstellen technisch abgebildet werden.
API Ökosysteme
Für Programmierschnittstellen hat sich der Begriff API eingebürgert. Dahinter verbirgt sich die Idee, dass angeforderte Daten aus Software-Produkten und –Modulen über einen klar definierten Weg angezapft werden. Diese Schnittstellen sollen zuverlässig und stabil sein. Jedes autonome Team hat die Verantwortung für diese. Gleichzeitig bieten API’s den Partnern einen transparenten Kommunikationsweg.
Jedes Team hegt und pflegt seine eigenen Schnittstellen und greift auf die API’s anderer Teams zurück. Das Resultat ist dann wie ein Ökosystem, das gehegt und gepflegt werden muss. Wildwuchs bestraft sich selbst.
Wachstum
Wenn ein Entwicklungsteam zu groß wird und sich teilt, dann muss auch die Schnittstelle nach außen aufgeteilt werden. Hierzu ist ein Refactoring des Codes unumgänglich. Dies ist eine Herausforderung, da die Schnittstelle nach außen, zu anderen Teams, weiterhin stabil bleiben muss. Nehmen wir ein Unternehmen wie Amazon oder Twitter. Es wäre nicht sehr angenehm, wenn die Partner bei jeder Teamänderung ein Softwareupdate vornehmen müssten. Eine Lösung kann hier ein zentraler API Service sein.
Feature im Blick
Wenn Teams an einem Produkt bauen, das sehr groß ist, dann stellt sich für Entwickler irgendwann die Frage, was das Ergebnis ihrer Entwicklung sein soll. Das große Ganze geht verloren. Sprint Goals sind häufig nicht aussagekräftig. Das Resultat ist dann, dass ein Entwicklungsteam nur wenig Verantwortung für das Ergebnis übernimmt. Ein Lösungsweg ist hier, das Gesamtprodukt vernünftig und sinnhaft zu modularisieren.
Anforderungen werden dann nicht wie am Fließband abgearbeitet, sondern das Produkt-Inkrement, als Ergebnis, ist im Blickfeld. Teams bauen Produkte mit Features und nicht Anforderungen. Das ist ein wesentlicher Unterschied zu dem oben genannten Szenario. Es wird Nutzwert ausgeliefert und nicht Code. Vielleicht werden aus hundert Zeilen Code vier, mit dem zigfachen Nutzwert. Weniger ist mehr. Solch ein Vorgehen ist nur dann möglich, wenn ein Team die Hoheit über sein Modul und Feature hat. Damit behält es auch die Verantwortlichkeit für seine Schnittstellen nach außen.
Modularisierung
In diesem Zusammenhang hat sich auch der Begriff Microservice gebildet. Ein Microservice ist jedoch eher eine technische Einheit. Ein Modul, so wie es hier gemeint ist, bezieht sich auf eine logische Einheit, die so groß ist, dass sie von einem Scrum Team verantwortet wird und kann somit mehrere Microservices umfassen. Ein Produkt, in diesem Sinne, kann mehrere Module umfassen.
Früher war die Definition von dem Umfang eines Produktes einfach dadurch definiert, dass es in einer Verpackung ausgeliefert wurde. Bei Produkten in der Cloud muss die Grenze zwischen Modul und Produkt im Einzelfall definiert werden. Diese Schnittstelle muss sauber verwaltet werden und darf nicht verwässern. Sie gestalten sich wie automatisierte Verträge zwischen Teams.
Docker Öko-Systeme
In den letzten Jahren ist das Konzept der Container aufgekommen. Am bekanntesten ist Docker4). Ein Container ist ein lauffähiges Modul, dass mit allen zugehörigen Teilen in ein Image verpackt ist und in einem Repository verwaltet wird. Er kann dann auf einer Orchestrierungsplattform ausgeführt werden. Das darunter liegende Betriebssystem ist so von der Software entkoppelt. Jeder Container hat seine Schnittstellen nach außen.
Dieses Konzept der Container können sich Teams zunutze machen, um den Betrieb der Module zu delegieren. Ein Container, oder eine Kombination davon, agieren wie ein
Microservice.
Desto mehr die Cloudanbieter aus dem Boden schießen, desto mehr sollte die Software Architektur so gewählt sein, dass der Anbieter austauschbar ist. Container sind ein wichtiger Baustein bei diesem Ziel. Die Anbieter können so auf Dauer die Orchestrierung der Container übernehmen. Die Scrum Teams können sich auf das konzentrieren was sie am besten können – Software entwickeln.
DevOps
Agile Teams wollen keine Trennung zwischen Development und Operations, weil sie damit die Verantwortung für den Erfolg ihres Produktes abgeben. Dieses Prinzip ist in den letzten Jahren unter dem Stichwort DevOps bekannt geworden. DevOps lässt sich mit der angebotenen Selbstbedienung bei den Cloudanbietern leicht realisieren.
Diese DevOps Teams werden häufig sehr schnell überlastet, wenn sie Defizite bei ihrer Infrastruktur aufweisen. Die Scrum Teams berichten, dass sie plötzlich mit allerhand Arbeit beschäftigt sind, die klassischerweise von Operations-Abteilungen erledigt werden. Wir sprechen hier auch von Infrastrukturschulden. Bei gut aufgestellten Scrum Teams wachsen die Anzahl von Kunden und Servern beliebig, ohne dass dies Anzahl der benötigten Teams erhöht. Fragen die wir von Developer Teams, die nach DevOps arbeiten hören, sind zum Beispiel „Müssen wir jetzt am Wochenende auf Stand-By sein?“ Dies ist nur ein Symptom für ein tiefer liegendes Problem. Cloud Architekturen sind noch in den Kinderschuhen. Wo früher die Operations-Abteilungen für Sicherheit und Kontrolle gesorgt haben, muss dies nun anders geregelt werden. Die Teams sind selbst dafür verantwortlich, dass ihre Systeme sicher sind.
Fazit
Agile Architekturen der Zukunft gestalten sich in der Cloud und werden dann zu Öko-Systemen, die sowohl die agilen Teams als auch die technologischen Herausforderungen beinhalten. Diese entstehen weiterhin am besten durch selbstorganisierten Teams.