Read in English · Leer en español · Lire en français
Abschnitt 2.6 von 2.8 · Mittelstufe · 22 Min. Lesezeit
Änderbarkeit, Testbarkeit und Deploybarkeit: auf Veränderung auslegen
Videolektion
5 Min. · auf Englisch gesprochen, mit UntertitelnNur anhören (Audio)
Transkript lesen
Der größte Teil der Kosten eines erfolgreichen Systems entsteht nach seinem ersten Release, wenn es wieder und wieder geändert wird. In dieser Lektion geht es darum, für diese Veränderung zu entwerfen.
Denken Sie an eine Küche. Ist der Herd in die Wand eingebaut und sind die Leitungen in Beton verlegt, muss man zum Austauschen die Wand einreißen. Wird er an eine Standardsteckdose angeschlossen, tauschen Sie ihn an einem Nachmittag aus. Bei Software ist es genauso. Teile, die sich ändern werden, bekommen Standardanschlüsse. Dann machen Sie es leicht zu prüfen, ob nach einem Austausch noch alles funktioniert, und machen die Auslieferung der neuen Version zur Routine statt zum Risiko.
Diese drei Schritte sind drei Qualitäten. Bei Änderbarkeit geht es um Kosten und Risiko einer Änderung. Bei Testbarkeit geht es darum, wie leicht Sie durch Tests zeigen können, dass sich das System wie beabsichtigt verhält. Und bei Deploybarkeit geht es darum, wie schnell, sicher und vorhersehbar eine Änderung in Produktion gelangt und wie schnell sie wieder zurückgenommen werden kann. Sie bilden einen Kreislauf: Ein modulares System ohne schnelle Tests ändert sich trotzdem langsam.
Änderbarkeit bedeutet nichts, solange Sie nicht sagen, was sich voraussichtlich ändern wird. Planen Sie für jede denkbare Änderung, überdimensionieren Sie; planen Sie für keine, wird jede Änderung zur Neuentwicklung. Stellen Sie also vier Fragen. Erstens: Was kann sich ändern – Funktionen, Plattformen, Partner oder Last? Zweitens: Wie wahrscheinlich ist das? Zahlungsanbieter und Steuerregeln ändern sich oft. Das Konzept einer Bestellung selten. Investieren Sie Designaufwand dort, wo Änderungen wahrscheinlich sind. Drittens: Wer nimmt die Änderung vor, und wann? Ein Entwickler im Code, ein Engineer über die Konfiguration oder ein Produktmanager, der ein Feature-Flag umlegt. Der Moment, in dem eine Entscheidung festgelegt wird, heißt ihr Bindungszeitpunkt. Und viertens: Was kostet sie an Aufwand, Zeit und Risiko? Die Antworten ergeben ein testbares Szenario.
Eine zentrale Taktik: Kopplung mit einem Vermittler verringern. Vorher sprechen Checkout, Erstattungen und Abonnements jeweils direkt mit jedem Zahlungsanbieter. Das sind sechs Abhängigkeiten, und ein neuer Anbieter bedeutet, drei Services zu ändern. Nachher hängen alle drei von einer Zahlungsschnittstelle ab, die die Anbieter dahinter verbirgt. Jeder Anbieter bekommt seinen eigenen Adapter. Einen Anbieter hinzuzufügen, bedeutet jetzt, einen Adapter hinzuzufügen, und die Aufrufer ändern sich überhaupt nicht.
Ein Essenslieferdienst bindet die Kassensysteme von Restaurants an. Jeder neue Anbieter kostet zwanzig Personentage für Arbeit und Tests. Bei sechshundert Pfund pro Tag sind das zwölftausend Pfund. Der Vertrieb erwartet dieses Jahr acht neue Anbieter: sechsundneunzigtausend Pfund. Der Architekt schlägt eine Adapter-Schnittstelle vor. Sie zu bauen, kostet einmalig achtzehntausend Pfund. Danach braucht jeder Anbieter nur noch vier Personentage: zweitausendvierhundert Pfund. Acht Anbieter kosten also insgesamt siebenunddreißigtausendzweihundert Pfund, eine Ersparnis von achtundfünfzigtausendachthundert Pfund im ersten Jahr. Die Investition hat sich mit dem zweiten Anbieter bezahlt gemacht. Aber nur, wenn die Anbieter wirklich kommen. Deshalb muss eine Änderbarkeitsanforderung sagen, was sich wahrscheinlich ändert.
Nun zur Testbarkeit. Eine Komponente ist testbar, wenn ein Test ihre Eingaben und ihren Zustand steuern und beobachten kann, was sie getan hat. Code, der einen echten Zahlungsdienst aufruft oder die Systemuhr direkt liest, ist schwer zu steuern. Die Lösung ist Dependency Injection. In Produktion hängt der Bestellservice nur von einer Payment-Gateway-Schnittstelle ab, implementiert von einem Gateway, das echte Netzwerkaufrufe ausführt. Im Unit-Test erhält derselbe Bestellservice stattdessen ein Fake-Gateway. Es liefert skriptgesteuerte Antworten und zeichnet jeden Aufruf auf, sodass der Test volle Kontrolle hat, ohne Netzwerk und ohne Warten.
Schließlich die Deploybarkeit. Die zentrale Idee sind kleine Batches. Ein Release mit einer einzigen Änderung ist leicht zu durchschauen und leicht zurückzurollen. Ein Release mit drei Monaten Arbeit enthält Hunderte zusammenwirkender Änderungen. Kleine Batches brauchen Automatisierung: eine Pipeline, die jede Änderung auf dieselbe Weise baut, testet und deployt, ohne manuelle Schritte, die jemand vergessen kann. Die Architektur hilft mit unabhängig deploybaren Teilen, abwärtskompatiblen Änderungen und schrittweisen Rollouts, zunächst für einen kleinen Teil des Traffics. Die Forschung des Programms DevOps Research and Assessment, kurz Dora, fand fünf Kennzahlen der Auslieferungsleistung und stellte fest, dass die besten Teams zugleich schnell und stabil sind. Lose gekoppelte Architektur geht mit besseren Werten einher.
Der vollständige Abschnitt behandelt Bindungszeitpunkte, die Arten von Test Doubles, einen teuren Deployment-Fehlschlag und die Dora-Metriken im Detail. Als Nächstes geht es in Abschnitt zwei Punkt sieben um Sicherheit, Benutzbarkeit und mehr. Bis gleich.
Was Sie wissen müssen
- Änderbarkeit beschreibt Kosten und Risiko von Änderungen; spezifizieren Sie sie, indem Sie angeben, was sich wahrscheinlich ändert, wer die Änderung vornimmt, wann sie gebunden wird und was die Änderung kosten darf.
- Taktiken für Änderbarkeit erhöhen die Kohäsion, verringern die Kopplung (kapseln, einen Vermittler nutzen, Abhängigkeiten beschränken) und verschieben die Bindung, doch jeder spätere Bindungszeitpunkt bringt zusätzliche Mechanik mit sich.
- Testbarkeit hängt von Steuerbarkeit und Beobachtbarkeit ab; isolieren Sie Abhängigkeiten hinter Schnittstellen und injizieren Sie sie, damit Tests Test Doubles verwenden können.
- Deploybarkeit beruht auf kleinen Batches, Automatisierung, unabhängig deploybaren Einheiten, abwärtskompatiblen Änderungen, schrittweisem Rollout und schnellem Rollback.
- Die aktuellen DORA-Metriken für die Softwareauslieferung sind Durchlaufzeit von Änderungen, Deployment-Häufigkeit, Wiederherstellungszeit nach fehlgeschlagenem Deployment, Änderungsfehlerrate und Deployment-Nacharbeitsrate.
- Wartbarkeit hat in ISO/IEC 25010:2023 fünf Teilmerkmale: Modularität, Wiederverwendbarkeit, Analysierbarkeit, Änderbarkeit und Testbarkeit.
Drei Qualitäten rund um Veränderung
Der größte Teil der Kosten eines erfolgreichen Systems entsteht nach seinem ersten Release, wenn es wieder und wieder geändert wird. Drei verwandte Qualitäten beschreiben, wie gut eine Architektur das unterstützt. Bei Änderbarkeit geht es um Kosten und Risiko einer Änderung. Bei Testbarkeit geht es darum, wie leicht Sie durch Tests zeigen können, dass sich das System (oder ein Teil davon) wie beabsichtigt verhält, und wie bereitwillig sich Fehlerursachen zeigen. Bei Deploybarkeit geht es darum, wie schnell, sicher und vorhersehbar eine Änderung in Produktion gebracht und wieder zurückgenommen werden kann.
Sie hängen in einem Kreislauf zusammen. Eine Änderung ist nur dann günstig, wenn Sie sie an einer Stelle vornehmen können (Änderbarkeit), schnell wissen, dass Sie nichts kaputt gemacht haben (Testbarkeit), und sie ohne großes Zeremoniell ausliefern können (Deploybarkeit). Ein modulares System ohne schnelle Tests ändert sich trotzdem langsam, weil jede Änderung wochenlange manuelle Regressionstests braucht. Ein System mit guten Tests, aber einem vierteljährlichen Release-Fenster liefert trotzdem langsam Nutzen.
Änderbarkeit: vier Fragen zu jeder Änderung
Bass, Clements und Kazman legen nahe, dass Änderbarkeit bedeutungslos ist, solange Sie nicht sagen, was sich voraussichtlich ändern wird. Wer für jede denkbare Änderung plant, erhält ein überdimensioniertes System voller ungenutzter Erweiterungspunkte; wer für keine plant, erhält ein System, in dem jede Änderung eine Neuentwicklung ist. Vier Fragen schärfen die Anforderung.
Was kann sich ändern? Funktionen, Plattformen (eine neue Datenbankversion, der Umzug in eine andere Cloud), die Umgebung (eine neue Partner-API, neue Vorschriften), Qualitäten (die doppelte Last) oder die Kapazität. Wie wahrscheinlich ist die Änderung? Investieren Sie Designaufwand dort, wo Änderungen wahrscheinlich sind: Zahlungsanbieter, Steuerregeln und Benutzeroberflächen ändern sich oft; das Konzept einer Bestellung selten. Wer nimmt die Änderung vor, und wann? Ein Entwickler beim Programmieren, ein Release-Engineer beim Deployment, ein Administrator über die Konfiguration oder ein Endbenutzer über Einstellungen. Der Moment, in dem eine Entscheidung festgelegt wird, heißt ihr Bindungszeitpunkt. Was kostet die Änderung? Aufwand, Dauer und Geld, um sie umzusetzen, zu testen und zu deployen, dazu die Zahl der anderen betroffenen Elemente und das Risiko, Defekte einzuführen.
Die Antworten auf diese Fragen ergeben ein Szenario der Art, wie sie in Abschnitt 2.3 eingeführt wurde: Ein Entwickler fügt die Unterstützung für einen neuen Zahlungsanbieter hinzu, ändert außer der Konfiguration keine bestehenden Module, braucht dafür einschließlich Tests höchstens 3 Personentage, und die Fehler im Bezahlvorgang nehmen nicht zu.
Änderbarkeitsszenarien mit unterschiedlichen Quellen und Bindungszeitpunkten
| Wer ändert | Was sich ändert | Wann es bindet | Antwortmaß (Response Measure) |
|---|---|---|---|
| Entwickler | Einen neuen Lieferpartner zu einer Essenslieferplattform hinzufügen | Programmierzeit | Nur der Partner-Adapter ändert sich; umgesetzt, getestet und deployt innerhalb von 5 Tagen |
| Produktmanager | Einen neuen Checkout-Ablauf für 10 % der Benutzer einschalten | Laufzeit (Feature-Flag) | Wirkt innerhalb von 1 Minute, ohne Deployment |
| Operations-Engineer | Das System auf einen neuen Datenbankhost umstellen | Deployment (Konfiguration) | Keine Codeänderung; ein Pipeline-Lauf von unter 15 Minuten |
| Administrator beim Kunden | Ein benutzerdefiniertes Feld zu einer Rechnung hinzufügen | Laufzeit (Einstellungen) | Ohne Beteiligung des Anbieters; sofort verfügbar |
| Plattformteam | Das Web-Framework auf eine neue Hauptversion aktualisieren | Build-Zeit | Weniger als 20 Dateien ändern sich außerhalb eines Anti-Corruption Layer; unter 2 Wochen |
Taktiken für Änderbarkeit
Die Taktiken in Software Architecture in Practice senken die Kosten von Änderungen, indem sie begrenzen, wie weit eine Änderung ausstrahlt. Sie beruhen auf zwei alten Ideen, die in Kapitel 3 ausführlich behandelt werden. Kohäsion misst, wie stark die Verantwortlichkeiten innerhalb eines Moduls zusammengehören; Kopplung misst, wie stark ein Modul von einem anderen abhängt. Eine wahrscheinliche Änderung sollte ein einziges kohäsives Modul betreffen, und dieses Modul sollte lose an den Rest gekoppelt sein.
Kohäsion erhöhen. Teilen Sie ein Modul auf, das zwei unzusammenhängende Aufgaben erledigt (ein CustomerService, der sowohl die Anmeldung als auch Treuepunkte verwaltet), und verschieben Sie Verantwortlichkeiten dorthin, wo sie hingehören, damit eine wahrscheinliche Änderung an einer Stelle landet.
Kopplung verringern. Kapseln: Verbergen Sie die Interna eines Moduls hinter einer expliziten Schnittstelle, nach David Parnas’ Prinzip des Information Hiding (1972), damit Aufrufer nicht von dem abhängen können, was sich ändern kann. Einen Vermittler nutzen: Setzen Sie etwas zwischen zwei Beteiligte, sodass keiner den anderen direkt kennt: einen Adapter, einen Message Broker, einen Publish-Subscribe-Kanal, ein Repository vor einer Datenbank oder ein API-Gateway. Abhängigkeiten beschränken: Legen Sie fest, welche Module welche aufrufen dürfen (Schichtregeln, ein Modul, das nur im eigenen Paket sichtbar ist), und setzen Sie das mit Werkzeugen durch. Gemeinsame Dienste abstrahieren: Stellen Sie gemeinsames Verhalten einmal hinter einer Schnittstelle bereit, statt es zu kopieren.
Bindung verschieben. Legen Sie eine Entscheidung so spät fest, wie es nützlich ist, damit die Änderung später und von jemandem weiter weg vom Code vorgenommen werden kann: Konfigurationsdateien, Umgebungsvariablen, beim Start erkannte Plug-ins, Service Discovery und Feature-Flags. Jeder spätere Bindungszeitpunkt bringt zusätzliche Mechanik mit sich (zu validierende Konfiguration, zu entfernende Flags, versionierte Plug-in-Schnittstellen); verschieben Sie daher nur Entscheidungen, die wirklich variieren.
Mit einem Vermittler Änderungen eindämmen
Bindungszeitpunkt
Entscheidungshilfe
Entscheidungshilfe: Wie spät sollte diese Entscheidung gebunden werden?
Nutzen Sie sie, wenn ein Stakeholder sagt: „Das könnte sich ändern.“ Beginnen Sie oben und hören Sie beim ersten Ja auf.
- Ist die Änderung unwahrscheinlich, oder bräuchte sie ohnehin neuen Code und neue Tests?JaBinden Sie zur Programmierzeit. Halten Sie es einfach und gut gekapselt, damit die Änderung lokal bleibt, wenn sie kommt.NeinWeiter zur nächsten Frage.
- Unterscheidet sich der Wert nur zwischen Umgebungen (Test, Staging, Produktion) oder zwischen den Installationen verschiedener Kunden?JaBinden Sie beim Deployment: Umgebungsvariablen oder von der Pipeline eingespeiste Konfiguration, versioniert in der Versionsverwaltung.NeinWeiter zur nächsten Frage.
- Müssen Dritte oder andere Teams Verhalten hinzufügen, ohne Ihren Code zu ändern?JaBinden Sie beim Start oder zur Laufzeit mit einer Plug-in- oder Erweiterungsschnittstelle, und versionieren Sie diese Schnittstelle sorgfältig.NeinWeiter zur nächsten Frage.
- Müssen Nicht-Entwickler Verhalten schnell ein- oder ausschalten können, oder müssen Sie zuerst für einen Teil der Benutzer freigeben?JaBinden Sie zur Laufzeit mit einem Feature-Flag, und geben Sie jedem Flag einen Verantwortlichen und ein Entfernungsdatum.NeinBinden Sie zur Build- oder Deployment-Zeit; späteres Binden würde Mechanik hinzufügen, die niemand braucht.
Ausgearbeitetes Beispiel
Ausgearbeitetes Beispiel: Was ist das Änderbarkeitsszenario wert?
Ein Essenslieferdienst bindet die Kassensysteme von Restaurants an. Heute erfordert jeder neue Kassensystem-Anbieter Änderungen an den Services für Speisekarte, Bestellungen und Erstattungen: etwa 15 Personentage Arbeit plus einen Regressionstestzyklus von 5 Tagen. Der Vertrieb erwartet in den nächsten 12 Monaten 8 neue Anbieter. Der Architekt schlägt eine Adapter-Schnittstelle für Anbieter vor (wie im Diagramm oben). Nehmen Sie Vollkosten von £600 pro Personentag an.
| Kosten pro Anbieter heute | 15 + 5 = 20 Personentage, also 20 x £600 = £12.000 |
|---|---|
| Kosten für 8 Anbieter heute | 8 x £12,000 = £96,000 |
| Einmalige Kosten des Refactorings | Schnittstelle entwerfen und bauen und die 3 bestehenden Anbieter migrieren: 30 Personentage = £18.000 |
| Kosten pro Anbieter danach | Einen Adapter schreiben (3 Tage) plus Contract Tests gegen die Schnittstelle (1 Tag): 4 Personentage = £2400 |
| Kosten für 8 Anbieter danach | £18,000 + 8 x £2,400 = £37,200 |
| Einsparung im ersten Jahr | £96,000 - £37,200 = £58,800 |
| Break-even | Jeder Anbieter spart £12.000 - £2400 = £9.600, also sind die £18.000 nach £18.000 / £9600 = 1,9 zurückverdient, das heißt mit dem zweiten neuen Anbieter |
Die Rechnung ist nur so gut wie die Vorhersage der Änderungen. Gewinnt der Vertrieb keine neuen Anbieter, ist das Refactoring reine Kosten. Deshalb müssen Änderbarkeitsanforderungen sagen, was sich wahrscheinlich ändert.
Die Durchlaufzeit zählt oft mehr als die Kosten: Wird der Start eines Anbieters von etwa 4 Wochen auf unter 1 Woche verkürzt, kann das Aufträge gewinnen, was keine Personentage-Rechnung erfasst.
Die neue Adapter-Schnittstelle ist selbst eine Festlegung. Sie später zu ändern, betrifft jeden Adapter; daher verdient sie sorgfältiges Design und Versionierung.
Testbarkeit: Steuerbarkeit und Beobachtbarkeit
Eine Komponente ist testbar, wenn ein Test sie in einen bekannten Zustand versetzen, ihr gewählte Eingaben geben und sehen kann, was sie getan hat. Zwei Eigenschaften erfassen das. Steuerbarkeit ist die Fähigkeit, die Eingaben und den internen Zustand einer Komponente aus einem Test heraus festzulegen. Beobachtbarkeit (im Sinne des Testens) ist die Fähigkeit, ihre Ausgaben und den relevanten internen Zustand zu sehen. Code, der die Systemuhr direkt liest, einen echten Zahlungsdienst aufruft, Zufallszahlen wählt oder in eine gemeinsame Datenbank schreibt, ist schwer zu steuern; Code, der seine Ergebnisse in privatem Zustand oder nur im Logtext verbirgt, ist schwer zu beobachten.
Architekturtaktiken für Testbarkeit zielen daher darauf, Tests Kontrolle und Einblick zu geben und die Komplexität zu begrenzen. Isolieren Sie Abhängigkeiten hinter Schnittstellen und nutzen Sie dann Dependency Injection: Die Komponente erhält ihre Kollaborateure (eine Uhr, ein Payment-Gateway, ein Repository) von außen, statt sie selbst zu erzeugen, sodass ein Test einen Ersatz übergeben kann. Diese Ersatzobjekte sind Test Doubles, ein von Gerard Meszaros bekannt gemachter Begriff: Ein Stub liefert vorgefertigte Antworten, ein Fake ist eine funktionierende, leichtgewichtige Implementierung (ein In-Memory-Repository), ein Mock prüft, dass erwartete Aufrufe erfolgt sind, und ein Spy zeichnet Aufrufe für spätere Assertions auf. Stellen Sie Testschnittstellen bereit: Hooks, um Zustand zu setzen, Traffic aufzuzeichnen und wiederzugeben oder in einer Sandbox-Umgebung zu laufen. Begrenzen Sie Nichtdeterminismus: Vermeiden Sie versteckte Nebenläufigkeit und globalen Zustand, und machen Sie Zeit und Zufall injizierbar. Begrenzen Sie strukturelle Komplexität: Weniger Abhängigkeiten und keine Zyklen bedeuten kleinere Test-Setups.
Die Architektur prägt die Teststrategie auch auf höheren Ebenen. In einem System aus Services braucht jede Grenze Contract Tests, die prüfen, dass beide Seiten sich über die API einig sind, und einige End-to-End-Tests, die den echten Pfad durchlaufen. Ein Design mit klaren Grenzen lässt die meisten Tests schnell und isoliert laufen, während ein verworrenes Design langsame, fragile End-to-End-Tests für alles erzwingt.
Dependency Injection macht eine Komponente steuerbar
class OrderService:
def __init__(self, gateway, clock):
self.gateway = gateway # anything with charge(amount, card)
self.clock = clock # anything with now()
def place(self, order):
if self.clock.now().hour >= 23:
return "kitchen closed"
return self.gateway.charge(order.total, order.card)
# In a test: full control, no network, no waiting until 11 pm
class FakeClock:
def __init__(self, t): self.t = t
def now(self): return self.t
class FakeGateway:
def __init__(self): self.calls = []
def charge(self, amount, card):
self.calls.append(amount)
return "approved"Deploybarkeit
Deploybarkeit misst, wie vorhersehbar und günstig eine Änderung vom Commit eines Entwicklers in die Produktion gelangt und wie schnell sie rückgängig gemacht werden kann. Zu einer vollwertigen Qualität wurde sie erst im letzten Jahrzehnt, als Continuous Delivery zeigte, dass Release-Häufigkeit und Stabilität keine Gegensätze sind. Die vierte Auflage von Software Architecture in Practice (2021) hat ihr ein Kapitel hinzugefügt.
Die zentrale Idee sind kleine Batches. Ein Release mit einer einzigen Änderung ist leicht zu testen, leicht zu durchschauen und leicht zurückzurollen; ein Release mit drei Monaten Arbeit enthält Hunderte zusammenwirkender Änderungen, sodass Ausfälle wahrscheinlich und schwer zu diagnostizieren sind. Kleine Batches erfordern Automatisierung: eine Deployment-Pipeline, die jede Änderung auf dieselbe Weise baut, testet und deployt, skriptgesteuerte Infrastruktur und keine manuellen Schritte, die jemand vergessen kann. Zu den Architekturtaktiken gehören unabhängig deploybare Einheiten (damit das Release eines Teams nicht auf das eines anderen wartet), abwärtskompatible Schnittstellen und Datenbankmigrationen, Mechanismen für Rollback und Roll-forward, schrittweise Rollouts (Canary Releases zunächst für einen kleinen Teil des Traffics, Blue-Green-Umschalten zwischen zwei Umgebungen) und Feature-Flags, die das Deployen von Code vom Freigeben einer Funktion für Benutzer trennen. Pipelines und Strategien werden in CI/CD-Pipelines und Deployment-Strategien behandelt.
Die Kosten, Deploybarkeit zu vernachlässigen, können gravierend sein. Im August 2012 deployte das Handelsunternehmen Knight Capital neuen Code manuell auf seine acht Order-Routing-Server, übersah aber einen. Ein wiederverwendetes Konfigurations-Flag aktivierte dann auf diesem Server veralteten Code, der den Markt mit Orders überflutete, in rund 45 Minuten etwa 4 Millionen Ausführungen erzeugte und das Unternehmen etwa 460 Millionen US-Dollar kostete. Ein automatisiertes, verifiziertes Deployment und das Entfernen toten Codes hätten es jeweils verhindert.
Auslieferung messen: die DORA-Metriken
Das DORA-Forschungsprogramm (DevOps Research and Assessment, beschrieben in Accelerate von Nicole Forsgren, Jez Humble und Gene Kim, 2018, und fortgeführt in Jahresberichten, die heute innerhalb von Google Cloud erstellt werden) fand heraus, dass eine kleine Zahl von Kennzahlen die Leistung der Softwareauslieferung vorhersagt und dass die Besten zugleich schnell und stabil sind. Das aktuelle Modell hat fünf DORA-Metriken für die Softwareauslieferung, gegliedert in Durchsatz und Instabilität. Ihre Namen haben sich entwickelt: Aus der alten Mean Time to Restore
wurde 2023 die Wiederherstellungszeit nach fehlgeschlagenem Deployment, und die Deployment-Nacharbeitsrate kam 2024 hinzu.
Zwei Vorbehalte. Erstens beschreiben diese Metriken das Auslieferungssystem eines Teams, nicht Einzelpersonen; wer damit Menschen in eine Rangfolge bringt, lädt zum Schönen der Zahlen ein. Zweitens sind sie Ergebnisse. Die Architektur beeinflusst sie stark: Teams, die ihren Teil unabhängig deployen, isoliert testen und schnell zurückrollen können, schneiden besser ab; das ist ein Grund, warum die DORA-Forschung lose gekoppelte Architektur mit höherer Auslieferungsleistung verbindet.
DORA-Metriken für die Softwareauslieferung (dora.dev, aktuelles Modell)
| Metrik | Gruppe | Was sie misst | Architektonische Hebel |
|---|---|---|---|
| Durchlaufzeit von Änderungen | Durchsatz | Zeit vom Commit einer Änderung in die Versionsverwaltung bis zu ihrem Lauf in Produktion | Schnelle automatisierte Tests, kleine unabhängig deploybare Einheiten, keine Übergaben |
| Deployment-Häufigkeit | Durchsatz | Wie oft Änderungen in Produktion deployt werden (oder die Zeit zwischen Deployments) | Unabhängige Deploybarkeit, automatisierte Pipeline, Feature-Flags |
| Wiederherstellungszeit nach Fehl-Deployment | Durchsatz | Zeit bis zur Erholung von einem Deployment, das fehlschlägt und sofortiges Eingreifen erfordert | Automatisiertes Rollback, Canary Releases, gutes Monitoring, kleine Änderungen |
| Änderungsfehlerrate | Instabilität | Anteil der Deployments, die sofortiges Eingreifen erfordern, etwa ein Rollback oder einen Hotfix | Testbarkeit, Contract Tests, abwärtskompatible Änderungen |
| Deployment-Nacharbeitsrate | Instabilität | Anteil der Deployments, die ungeplant sind und wegen eines Incidents in Produktion erfolgen | Qualität von Tests und Reviews; Observability, die Probleme früh erkennt |
Wartbarkeit in ISO/IEC 25010
ISO/IEC 25010:2023 fasst diese Anliegen unter dem Merkmal Wartbarkeit zusammen, mit fünf Teilmerkmalen: Modularität (das System besteht aus getrennten Komponenten, sodass eine Änderung an einer möglichst wenig Auswirkung auf andere hat), Wiederverwendbarkeit (ein Bestandteil kann in mehr als einem System oder beim Bau anderer Bestandteile verwendet werden), Analysierbarkeit (wie leicht sich die Auswirkung einer Änderung beurteilen, ein Mangel diagnostizieren oder die zu ändernden Teile finden lassen), Änderbarkeit (das System kann geändert werden, ohne Defekte einzuführen oder die Qualität zu mindern) und Testbarkeit (Testkriterien können festgelegt und Tests durchgeführt werden, um zu bestimmen, ob sie erfüllt sind). Deploybarkeit hat im Standard kein eigenes Teilmerkmal; Installierbarkeit und Austauschbarkeit gehören zur Flexibilität. Das Modell ist eine Checkliste, wie Abschnitt 2.2 erklärt; erst Szenarien machen jeden Punkt konkret.
Prüfen Sie Ihr Verständnis
Warum ist „Das System soll leicht änderbar sein“ keine brauchbare Anforderung?
Sie sagt nicht, was sich ändern wird, wer es ändert, wann oder welche Kosten akzeptabel sind; daher kann niemand dafür entwerfen oder prüfen, ob sie erfüllt ist.
Was ist der Unterschied zwischen einem Stub und einem Mock?
Ein Stub liefert vorgefertigte Antworten, damit der Test Eingaben steuern kann; ein Mock prüft zusätzlich, dass die erwarteten Aufrufe erfolgt sind, sodass der Test Interaktionen verifiziert.
Warum verbessern Feature-Flags die Deploybarkeit?
Sie trennen das Deployen von Code vom Freigeben einer Funktion, sodass unfertige oder riskante Funktionen ausgeschaltet deployt, schrittweise freigegeben und ohne neues Deployment wieder ausgeschaltet werden können.
Ein Team deployt monatlich, und jedes Release enthält etwa 200 Änderungen. Welche DORA-Metriken leiden wahrscheinlich, und warum?
Die Durchlaufzeit von Änderungen (Änderungen warten wochenlang auf das Release), die Deployment-Häufigkeit und wahrscheinlich auch Änderungsfehlerrate und Wiederherstellungszeit, weil große Batches eher fehlschlagen und schwerer zu diagnostizieren und zurückzurollen sind.
Quellen und weiterführende Literatur
Haben Sie eine Frage zu diesem Abschnitt? ArchitectBot, der KI-Lernassistent des Kurses, antwortet zuerst aus dem Kurs.
Fragen: „Wir haben einen Monolithen, der vor jedem Release drei Wochen manuell getestet wird. Welche Architekturänderungen würden uns wöchentliche Deployments ohne mehr Risiko ermöglichen?“