Agile Softwareentwicklung mit C# (Microsoft Press) - Gary McLean Hall - ebook

Agile Softwareentwicklung mit C# (Microsoft Press) ebook

Gary McLean Hall

0,0

Opis

Wie geht man am besten mit wechselnden Anforderungen im Lauf eines Softwareprojektes um? Wie kann man Änderungen im Code einfach, zeitsparend und ohne Fehler umsetzen? Agile Methoden und Prozesse wie Scrum helfen, aber auch der Code selbst muss adaptiv und agil sein.  Zentrales Thema dieses Buchs ist die Entwicklung von anpassungsfähigem C#-Code, der agilen Teams die Arbeit erleichtert und bewährte Prinzipien der objektorientierten Programmierung (insbesondere SOLID) berücksichtigt. Das Ergebnis ist ein praxisorientiertes Werk, das Ihnen anhand vieler Code-Beispiele verdeutlicht, wie Sie in einem agilen Umfeld Code schreiben können, der flexibel und adaptiv ist. Lernen Sie, wie Sie Unit Tests richtig einsetzen, welche Methoden der Refaktorierung effektiv sind, wie Sie wichtige Patterns verwenden und gefährliche Anti-Patterns vermeiden. Dieses Buch macht Ihren Code agil! · Die Scrum-Grundlagen: Artefakte, Rollen, Kennzahlen und Phasen · Organisation und Management von Abhängigkeiten · Best Practices für Patterns und Anti-Patterns · Beherrschung der SOLID-Prinzipien: Single-Responsibility, Open/Closed, Liskovsche Substitution · Schnittstellen richtig managen, um anpassungsfähigen Code zu erhalten · Unit-Tests und Refaktorierung im Zusammenspiel · Einfluss von Delegation und Abstraktion auf die Anpassungsfähigkeit von Code · Implementierung von Dependency-Injection · Die praktische Anwendung dieser Prinzipien im Rahmen eines agilen Projekts

Ebooka przeczytasz w aplikacjach Legimi na:

Androidzie
iOS
czytnikach certyfikowanych
przez Legimi
Windows
10
Windows
Phone

Liczba stron: 550

Odsłuch ebooka (TTS) dostepny w abonamencie „ebooki+audiobooki bez limitu” w aplikacjach Legimi na:

Androidzie
iOS



Gary McLean Hall lebt mit seiner Frau, seiner Tochter und ihrem Hund in Manchester, England. Er ist ein erfahrener Microsoft .NET Framework-Entwickler, der sich auf Patterns und Best Practices spezialisiert hat. In vielen Jahren als Softwareentwickler hat er in zahlreichen agilen Teams gearbeitet, die sich stark auf das Ziel konzentriert haben, Code zu erstellen, der äußerst anpassungsfähig ist. Er hat für Unternehmen wie Eidos, Xerox, Nephila Capital Ltd. und The LateRooms Group gearbeitet. Außerdem hat er mehrere Jahre lang ein Softwareconsultingunternehmen geleitet und drei Jahre lang auf Bermuda gelebt und gearbeitet. In allen Rollen hat er es immer geschafft, eine beeindruckende Balance zwischen pünktlicher Auslieferung eines Softwareprodukts und der Qualität seines Quellcodes zu finden.

Zu diesem Buch – sowie zu vielen weiteren dpunkt.büchern – können Sie auch das entsprechende E-Book im PDF-Format herunterladen. Werden Sie dazu einfach Mitglied bei dpunkt.plus+:

www.dpunkt.de/plus

Agile Softwareentwicklung mit C#

Best Practices und Patterns für flexiblen und adaptiven C#-Code

Gary McLean Hall

Gary McLean Hall

Übersetzung: Detlef Johannis, KemptenLektorat: Thomas Braun-Wiesholler, MünchenCopy-Editing: Dorothee Klein, SiegenHerstellung: Frank HeidtSatz: Gerhard Alfes, mediaService, Siegen, www.mediaservice.tvUmschlaggestaltung: Helmut Kraus, www.exclam.deDruck und Bindung: M.P. Mediaprint Informationsdienste, Paderborn

Bibliografische Information der Deutschen NationalbibliothekDie Deutsche Nationalbibliothek verzeichnet diese Publikation in der Deutschen Nationalbibliografie;detaillierte bibliografische Daten sind im Internet über http://dnb.d-nb.de abrufbar.

ISBN:Buch 978-3-86490-285-7PDF 978-3-86491-690-8ePub 978-3-86491-691-5

Translation Copyright für die deutschsprachige Ausgabe © 2015 dpunkt.verlag GmbHWieblinger Weg 1769123 Heidelberg

Copyright der amerikanischen Originalausgabe © Gary McLean Hall, 2014Title of American original: Adaptive Code via C#Published by Microsoft PressISBN: 978-0-321-94854-0

Die vorliegende Publikation ist urheberrechtlich geschützt. Alle Rechte vorbehalten. Die Verwendung der Texte und Abbildungen, auch auszugsweise, ist ohne die schriftliche Zustimmung des Verlags urheberrechtswidrig und daher strafbar. Dies gilt insbesondere für die Vervielfältigung, Übersetzung oder die Verwendung in elektronischen Systemen.Es wird darauf hingewiesen, dass die im Buch verwendeten Soft- und Hardware-Bezeichnungen sowie Markennamen und Produktbezeichnungen der jeweiligen Firmen im Allgemeinen warenzeichen-, marken- oder patentrechtlichem Schutz unterliegen.Alle Angaben und Programme in diesem Buch wurden mit größter Sorgfalt kontrolliert. Weder Autor noch Verlag können jedoch für Schäden haftbar gemacht werden, die in Zusammenhang mit der Verwendung dieses Buches stehen.

5 4 3 2 1 0

Für Amelia Rose

– Gary McLean Hall

Inhaltsübersicht

Einführung

TEIL I    Eine agile Grundlage

Kapitel 1       Einführung in Scrum

Kapitel 2       Abhängigkeiten und Schichten

Kapitel 3       Schnittstellen und Entwurfs-Patterns

Kapitel 4       Unit-Tests und Refaktorierung

TEIL II    Schreiben von SOLID-Code

Kapitel 5        Das Single-Responsibility-Prinzip

Kapitel 6        Das Open/Closed-Prinzip

Kapitel 7        Das Liskovsche Substitutionsprinzip

Kapitel 8        Interface-Segregation

Kapitel 9        Dependency-Injection

TEIL III    Entwickeln von adaptivem Code in der Praxis

Kapitel 10         Beispiel für die Entwicklung von adaptivem Code: Einführung

Kapitel 11         Beispiel für die Entwicklung von adaptivem Code: Sprint 1

Kapitel 12         Beispiel für die Entwicklung von adaptivem Code: Sprint 2

TEIL IV    Anhang

Anhang A         Adaptive Tools

Anhang B         GitHub-CodebeispieleStichwortverzeichnis

Inhaltsverzeichnis

Einführung

Wer sollte dieses Buch lesen

Aufbau dieses Buchs

Konventionen in diesem Buch

Systemvoraussetzungen

Downloads: Codebeispiele

Danksagungen

Errata und Support

Kostenlose E-Books von Microsoft Press

TEIL I      Eine agile Grundlage

Kapitel 1     Einführung in Scrum

Scrum und Wasserfall

Rollen und Verantwortungsbereiche

Product Owner

Scrum Master

Entwicklungsteam

Schweine und Hühner

Artefakte

Das Scrum-Board

Diagramme und Kennzahlen

Backlogs

Der Sprint

Releaseplanung

Sprintplanung

Daily Scrum

Sprintvorführung

Sprint-Retrospektive

Scrum-Kalender

Probleme beim Einsatz von Scrum und Agile

Nicht adaptiver Code

Zusammenfassung

Kapitel 2     Abhängigkeiten und Schichten

Die Definition von Abhängigkeit

Ein simples Beispiel

Modellieren von Abhängigkeiten in einem gerichteten Graphen

Verwalten von Abhängigkeiten

Implementierungen und Schnittstellen

Der verdächtige Geruch von new

Alternativen zur Objekterstellung

Das Anti-Pattern Entourage

Das Stairway-Pattern

Auflösen von Abhängigkeiten

Abhängigkeitsverwaltung mit NuGet

Schichten

Wichtige Patterns

Grenzüberschreitende Angelegenheiten

Asymmetrische Schichteinteilung

Zusammenfassung

Kapitel 3     Schnittstellen und Entwurfs-Patterns

Was ist eine Schnittstelle?

Syntax

Explizite Implementierung

Polymorphie

Adaptive Entwurfs-Patterns

Das Null-Object-Pattern

Das Adapter-Pattern

Das Strategy-Pattern

Mehr Vielseitigkeit

Duck-Typing

Mixins

Flüssige Schnittstellen

Zusammenfassung

Kapitel 4     Unit-Tests und Refaktorierung

Unit-Tests

Arrange, Act, Assert

Testorientierte Entwicklung

Komplexere Tests

Refaktorieren

Vorhandenen Code ändern

Ein neuer Kontotyp

Zusammenfassung

TEIL II     Schreiben von SOLID-Code

Kapitel 5     Das Single-Responsibility-Prinzip

Das Problem

Refaktorieren, um die Übersichtlichkeit zu verbessern

Refaktorieren, um Abstraktion zu erreichen

SRP und das Decorator-Pattern

Das Composite-Pattern

Predicate-Decorator

Branching-Decorator

Lazy-Decorator

Logging-Decorator

Profiling-Decorator

Asynchronous-Decorator

Decorator für Eigenschaften und Ereignisse

Verwenden des Strategy-Patterns statt switch

Zusammenfassung

Kapitel 6     Das Open/Closed-Prinzip

Einführung in das Open/Closed-Prinzip

Die Meyer-Definition

Die Martin-Definition

Fehlerkorrekturen

Lose Kopplung

Erweiterungspunkte

Code ohne Erweiterungspunkte

Virtuelle Methoden

Abstrakte Methoden

Schnittstellenvererbung

Vererbung in den Entwurf einarbeiten

Geschützte Variation

Prognostizierte Variation

Eine stabile Schnittstelle

Gerade genug Anpassungsfähigkeit

Zusammenfassung

Kapitel 7     Das Liskovsche Substitutionsprinzip

Einführung in das Liskovsche Substitutionsprinzip

Formale Definition

LSP-Regeln

Verträge

Vorbedingungen

Nachbedingungen

Dateninvarianten

Liskovsche Vertragsregeln

Codeverträge

Kovarianz und Kontravarianz

Definitionen

Liskovsche Typsystemregeln

Zusammenfassung

Kapitel 8     Interface-Segregation

Ein Beispiel für Interface-Segregation

Eine einfache CRUD-Schnittstelle

Caching

Dekorieren mehrerer Schnittstellen

Verwenden von Schnittstellen in Clients

Mehrere Implementierungen, mehrere Instanzen

Einzelne Implementierung, einzelne Instanz

Das Interface-Soup-Anti-Pattern

Zerlegen von Schnittstellen

Anforderungen des Clients

Anforderungen der Architektur

Schnittstellen mit einer einzigen Methode

Zusammenfassung

Kapitel 9     Dependency-Injection

Bescheidene Anfänge

Die Aufgabenlistenanwendung

Erstellen des Objektgraphen

Inversion of Control

Jenseits der simplen Injection

Das Service-Locator-Anti-Pattern

Das Illegitimate-Injection-Anti-Pattern

Die Composition-Root

Konvention vor Konfiguration

Zusammenfassung

TEIL III      Entwickeln von adaptivem Code in der Praxis

Kapitel 10      Beispiel für die Entwicklung von adaptivem Code: Einführung

Trey Research

Das Team

Das Produkt

Anfängliches Backlog

User Stories in Prosabeschreibungen finden

Abschätzen der Story-Punkte

Zusammenfassung

Kapitel 11      Beispiel für die Entwicklung von adaptivem Code: Sprint 1

Planung

»Ich will Räume anlegen, um Unterhaltungen thematisch einzugrenzen.«

Der Controller

Das Raum-Repository

»Ich will eine Liste der Räume ansehen, die Unterhaltungen repräsentieren.«

»Ich will die Nachrichten ansehen, die an einen Raum geschickt wurden.«

»Ich will reine Textnachrichten an andere Raummitglieder schicken.«

Sprintvorführung

Erste Vorführung von Proseware

Sprint-Retrospektive

Was lief gut?

Was lief schlecht?

Was sollte sich ändern?

Was sollte beibehalten werden?

Überraschungen?

Zusammenfassung

Kapitel 12      Beispiel für die Entwicklung von adaptivem Code: Sprint 2

Planung

»Ich will Markdown senden, der richtig formatiert ist.«

»Ich will Nachrichteninhalte so filtern, dass sie nicht anstößig sind.«

»Ich will Hunderte von Benutzern gleichzeitig bedienen.«

Sprintvorführung

Sprint-Retrospektive

Was lief gut?

Was lief schlecht?

Was sollte sich ändern?

Was sollte beibehalten werden?

Überraschungen?

Zusammenfassung

TEIL IV    Anhang

Anhang A     Adaptive Tools

Quellcodeverwaltung mit Git

Kontinuierliche Integration

Anhang B     GitHub-Codebeispiele

Stichwortverzeichnis

Einführung

Der Begriff adaptiver Code aus dem Untertitel dieses Buchs liefert eine gute Beschreibung für das Ergebnis, das Sie erhalten, wenn Sie die Prinzipien des Buchs anwenden: die Fähigkeit von Code, sich an alle neuen Anforderungen oder unvorhergesehenen Szenarien anpassen zu lassen, ohne dass er dafür in weiten Teilen umgearbeitet werden muss. Dieses Buch hat das Ziel, viele der aktuellen Best Practices aus dem Bereich der C#-Programmierung mit dem Microsoft .NET Framework in einem Band zusammenzufassen. Ein Teil des Inhalts wird zwar auch in anderen Büchern behandelt, aber diese Bücher konzentrieren sich entweder stark auf die Theorie oder sind nicht spezifisch auf die .NET-Entwicklung zugeschnitten.

Programmierung kann ein langsamer Prozess sein. Wenn Ihr Code adaptiv ist, sind Sie in der Lage, Änderungen schneller, einfacher und mit weniger Fehlern vorzunehmen, als wenn Sie mit einer Codebasis arbeiten, die Änderungen behindert. Wie jeder Entwickler weiß, ändern sich Anforderungen. Auf welche Weise mit diesen Änderungen umgegangen wird, macht den Unterschied zwischen erfolgreichen Softwareprojekten und denen aus, die aufgrund eines völlig außer Kontrolle geratenen Umfangs steckenbleiben. Entwickler können auf unterschiedliche Arten auf Änderungen der Anforderungen reagieren, wobei zwei gegensätzliche Standpunkte die Extreme des Spektrums bilden.

Erstens können Entwickler einen inflexiblen Standpunkt einnehmen. Bei diesem Ansatz ist das Projekt angefangen beim Entwicklungsprozess bis hinunter zum Klassenentwurf so inflexibel, als wäre es vor 50 Jahren mithilfe von Lochkarten implementiert worden. Wasserfall-Methodologien sind bekannte Vertreter dieser Zunft, der es darum geht sicherzustellen, dass sich Software nicht nach Belieben verändern darf. Ihr Beharren darauf, dass die Phasen von Analyse, Entwurf, Implementierung und Testen voneinander isoliert bleiben und nur in einer Richtung nacheinander abgearbeitet werden, macht es schwierig oder zumindest teuer für den Kunden, irgendwelche Anforderungen zu verändern, nachdem die Implementierung erst einmal begonnen hat. Der Code braucht daher gar nicht so beschaffen zu sein, dass er leicht zu ändern ist: Der Prozess verbietet praktisch Änderungen.

Der zweite Ansatz, agile Methodologie, besteht nicht etwa darin, lediglich eine Alternative zu solch inflexiblen Methodologien zu finden. Er will eine Reaktion auf sie sein. Agile Prozesse haben sich das Ziel gesetzt, Änderungen als unerlässlichen Teil des Vertrags zwischen Kunde und Entwickler willkommen zu heißen. Wenn Kunden etwas an dem Produkt, für das sie bezahlen, verändern wollen, sollten der Zeitaufwand und die finanziellen Kosten den Umfang der Änderung widerspiegeln, aber nicht abhängig von der Phase sein, in der sich der Prozess momentan befindet. Im Unterschied zu anderen technischen Disziplinen arbeitet Software-Engineering mit einem äußerst elastischen Werkzeug: Quellcode. Die Steine und Mörtel, aus denen ein Haus entsteht, werden fest miteinander verbunden, während der Bau fortschreitet. Der Aufwand, um den Entwurf eines Hauses zu verändern, hängt natürlich davon ab, in welcher Phase sich der Bauprozess befindet. Hat der Bau noch gar nicht begonnen (wenn also bisher nur Pläne vorliegen), ist eine Änderung relativ billig. Sind die Fenster eingebaut, die elektrischen Leitungen verlegt und die Wasserrohre angeschlossen, wäre es unglaublich teuer, das obere Badezimmer nach unten neben die Küche zu verlegen. Bei Code sollte es nicht so aufwendig sein, Features zu verschieben und die Navigation einer Benutzeroberfläche umzugestalten. Leider ist das aber nicht immer der Fall. Allein der Zeitaufwand verhindert oft solche Änderungen. Daran ist meiner Ansicht nach vor allem eine fehlende Anpassungsfähigkeit des Codes schuld.

Dieses Buch demonstriert den zweiten Ansatz und erklärt anhand von Praxisbeispielen die Vorgehensweise beim Implementieren adaptiven Codes.

Wer sollte dieses Buch lesen

Dieses Buch soll die Lücke zwischen Theorie und Praxis schließen. Der Leser, für den das Buch geschrieben wurde, ist ein erfahrener Programmierer, der eher praktische Beispiele für Entwurfs-Patterns, SOLID-Prinzipien, Unit-Tests, Refaktorierung und andere Techniken sucht.

Fortgeschrittene Programmierer, die Wissenslücken stopfen wollen oder Zweifel und Fragen darüber haben, wie wichtige Best Practices der Branche zusammenpassen, profitieren am meisten von diesem Buch, besonders weil der Alltag beim Programmieren nur selten den oft simplen Beispielen oder gar der Theorie entspricht. Weite Teile von SOLID sind bekannt, aber die Feinheiten des Open/Closed-Prinzips (siehe Kapitel 6) und des Liskovschen Substitutionsprinzips (Kapitel 7) werden nicht vollständig verstanden. Selbst erfahrenen Programmierern ist manchmal nicht völlig klar, welche Vorteile die Dependency-Injection bietet (Kapitel 9). Genauso wird oft übersehen, welche Flexibilität – und somit Anpassungsfähigkeit – Schnittstellen dem Code verleihen (Kapitel 3).

Dieses Buch kann auch unerfahrenen Entwicklern helfen, weil sie hier von Grund auf lernen, welche Aspekte bekannter Patterns und Best Practices nützlich sind und welche langfristig eher schädlich. Der Code, den ich von Stellenbewerbern oft zu sehen bekomme, hat viele Gemeinsamkeiten. Der allgemeine Entwurf zeigt, dass der Bewerber bei vielen Fähigkeiten fast soweit ist, aber noch ein wenig Unterstützung braucht, um ein deutlich besserer Programmierer zu werden. Besonders das Entourage-Anti-Pattern (Kapitel 2) und das Service-Locator-Anti-Pattern (Kapitel 9) sind in den präsentierten Codebeispielen allgegenwärtig. Praktische Alternativen und Begründungen, warum sie sinnvoller sind, werden in diesem Buch beschrieben.

Erforderliche Vorkenntnisse

Im Idealfall haben Sie bereits einige praktische Erfahrung im Programmieren mit einer Sprache, deren Syntax C# ähnelt, zum Beispiel Java oder C++. Sie sollten außerdem eine solide Grundlage in Konzepten der prozeduralen Programmierung haben, beispielsweise bedingte Verzweigungen, Schleifen und Ausdrücke. Und Sie sollten etwas Erfahrung in der objektorientierten Programmierung mit Klassen haben und von Schnittstellen wenigstens schon gehört haben.

Dieses Buch eignet sich wahrscheinlich nicht für Sie, wenn …

Dieses Buch eignet sich wahrscheinlich nicht für Sie, wenn Sie gerade erst anfangen, das Programmieren zu lernen. Dieses Buch behandelt fortgeschrittene Themen, die solide Kenntnisse grundlegender Programmierkonzepte voraussetzen.

Aufbau dieses Buchs

Dieses Buch besteht aus drei Teilen, die jeweils aufeinander aufbauen. Trotzdem müssen Sie das Buch nicht von Anfang bis Ende durchlesen. Jedes Kapitel ist in sich abgeschlossen und behandelt ein bestimmtes Thema. Wo es sinnvoll ist, finden Sie Querverweise auf andere Kapitel.

Teil I: Eine agile Grundlage

Dieser Teil schafft die Grundlage zum Erstellen von Software, die adaptiv ist. Er bietet einen Überblick über den agilen Prozess Scrum, für den Code benötigt wird, der sich einfach an Änderungen anpassen lässt. Die übrigen Kapitel in diesem Teil konzentrieren sich auf Details zu Schnittstellen, Entwurfs-Patterns, Refaktorierung und Unit-Tests.

Kapitel 1: Einführung in Scrum

Dieses Kapitel eröffnet das Buch mit einer Einführung in Scrum, eine agile Projektverwaltungsmethodologie. Das Kapitel bietet einen detaillierten Überblick über die Artefakte, Rollen, Kennzahlen und Phasen eines Scrum-Projekts. Es zeigt außerdem, wie Entwickler sich selbst und ihren Code organisieren sollten, wenn sie in einer agilen Umgebung tätig sind.

Kapitel 2: Abhängigkeiten und Schichten

Dieses Kapitel beschäftigt sich mit Abhängigkeiten und Schichtarchitektur. Code kann nur adaptiv sein, wenn die Struktur der Lösung dies zulässt. Es werden die unterschiedlichen Arten von Abhängigkeiten beschrieben: Eigenabhängigkeiten, Fremdabhängigkeiten und Frameworkabhängigkeiten. Das Kapitel beschreibt, wie Sie Abhängigkeiten verwalten und organisieren, von Anti-Patterns (die Sie vermeiden sollten) bis zu Patterns (die Sie nutzen sollten). Außerdem steigt es mit fortgeschrittenen Themen wie aspektorientierter Programmierung und asymmetrischer Schichtung tiefer in wichtige Programmiertechniken ein.

Kapitel 3: Schnittstellen und Entwurfs-Patterns

Schnittstellen sind in der modernen .NET-Entwicklung allgegenwärtig. Allerdings werden sie oft falsch verwendet, missverstanden und missbraucht. Dieses Kapitel zeigt einige bekannte und nützliche Entwurfs-Patterns und beschreibt, wie vielseitig eine Schnittstelle sein kann. Während das Kapitel den Leser durch die Schritte zur simplen Extrahierung einer Schnittstelle führt, zeigt es, wie Schnittstellen auf viele unterschiedliche Arten genutzt werden können, um ein Problem zu lösen. Mixins, Duck-Typing und flüssige Schnittstellen unterstreichen weiter die Vielseitigkeit dieser zentralen Waffe im Arsenal des Programmierers.

Kapitel 4: Unit-Tests und Refaktorierung

Zwei Techniken, die heutzutage jeder Programmierer beherrschen muss, sind Unit-Tests und Refaktorierung. Die beiden hängen eng miteinander zusammen und ihre Kombination produziert adaptiven Code. Ohne das Sicherheitsnetz von Unit-Tests ist die Refaktorierung fehlerträchtig. Und ohne Refaktorierung wird Code unhandlich, inflexibel und schwierig zu verstehen. Dieses Kapitel arbeitet ein Beispiel für Unit-Tests von bescheidenen Anfängen bis zu fortgeschrittenen, aber praktischen Patterns durch und stellt flüssige Assert-Verkettung, testorientierte Entwicklung und Mocking vor. Im Bereich der Refaktorierung demonstriert das Kapitel anhand praxisorientierter Beispiele, wie Sie die Lesbarkeit und Wartungsfreundlichkeit von Quellcode verbessern.

Teil II: Schreiben von SOLID-Code

Dieser Teil baut auf den Grundlagen auf, die in Teil I geschaffen wurden. Jedes Kapitel widmet sich einem Prinzip von SOLID. Dabei erklären diese Kapitel nicht einfach die trockene Theorie, sondern demonstrieren anhand von Praxisbeispielen die Umsetzung der Prinzipien. Indem jedes Beispiel in einen realen Kontext gesetzt wird, stellen die Kapitel in diesem Teil des Buchs den Nutzen von SOLID eindrucksvoll unter Beweis.

Kapitel 5: Das Single-Responsibility-Prinzip

Dieses Kapitel zeigt, wie Sie das Single-Responsibility-Prinzip in der Praxis mithilfe von Decorator- und Adapter-Pattern umsetzen. Die Anwendung des Prinzips führt dazu, dass mehr Klassen entstehen, diese Klassen aber kleiner werden. Das Kapitel zeigt, dass sich diese kleineren Klassen im Unterschied zu monolithischen Klassen, die einen großen Funktionsumfang enthalten, auf eine bestimmte Aufgabe beschränken und sich darauf konzentrieren, lediglich einen kleinen Teilaspekt eines größeren Problems zu lösen. In der Kombination mehrerer dieser Klassen zeigt sich dann die beeindruckende Leistungsfähigkeit der Einzelteile und des Gesamtsystems.

Kapitel 6: Das Open/Closed-Prinzip

Das Open/Closed-Prinzip klingt einfach, kann aber erhebliche Auswirkungen auf den Code haben. Es soll sicherstellen, dass Code, der den SOLID-Prinzipien folgt, nur erweitert, aber niemals bearbeitet wird. Dieses Kapitel stellt außerdem das Konzept der prognostizierten Variation in Bezug auf das Open/Closed-Prinzip vor und beschreibt, wie es Entwicklern hilft, mithilfe von Erweiterungspunkten die Anpassungsfähigkeit zu erhöhen.

Kapitel 7: Das Liskovsche Substitutionsprinzip

Dieses Kapitel zeigt, welche Vorteile es bringt, das Liskovsche Substitutionsprinzip auf Code anzuwenden. Besonders wird dabei auf die Tatsache eingegangen, dass diese Regeln helfen, das Open/Closed-Prinzip einzuhalten und versehentliche Beschädigungen aufgrund von Veränderungen zu verhindern. Es wird gezeigt, wie Verträge mit Vorbedingungen, Nachbedingungen und Dateninvarianten durch den Einsatz von Codeverträgen definiert und überprüft werden. Außerdem beschreibt das Kapitel wichtige Regeln zur Ableitung von Typen, zum Beispiel Kovarianz, Kontravarianz und Invarianz, und demonstriert die Auswirkungen, falls diese Regeln gebrochen werden.

Kapitel 8: Interface-Segregation

Nicht nur Klassen sollten kleiner sein, als sie oft sind, dieses Kapitel zeigt, dass auch Schnittstellen oft zu groß sind. Interface-Segregation ist eine simple Technik, die oft übersehen wird. Dieses Kapitel zeigt, welche Vorteile es hat, Schnittstellen möglichst klein zu halten und mit diesen kleinen Schnittstellen zu arbeiten. Außerdem nennt es unterschiedliche Gründe, die für das Auftrennen von Schnittstellen sprechen, zum Beispiel Anforderungen des Clients oder der Architektur.

Kapitel 9: Dependency-Injection

Dieses Kapitel beschäftigt sich mit dem Klebstoff, der die übrigen Techniken dieses Buchs zusammenhält. Ohne Dependency-Injection wäre vieles gar nicht möglich, sie ist wirklich derart wichtig. Dieses Kapitel enthält eine Einführung in Dependency-Injection und vergleicht die unterschiedlichen Methoden für ihre Implementierung. Das Kapitel behandelt die Verwaltung von Objektlebensdauern, die Arbeit mit Inversion-of-Control-Containern, das Vermeiden häufiger Anti-Patterns im Bereich von Diensten und das Analysieren von Composition-Roots und Resolution-Roots.

Teil III: Entwickeln von adaptivem Code in der Praxis

Dieser Teil demonstriert anhand einer Beispielanwendung, wie die im Buch beschriebenen Techniken kombiniert werden. Diese Kapitel enthalten eine Menge Code, er wird aber ausführlich erklärt. Weil dieses Buch sich mit der Arbeit in einer agilen Umgebung beschäftigt, orientieren sich die Kapitel an Scrum-Sprints und die durchgeführten Arbeiten sind das Ergebnis von Backlog-Einträgen und Änderungswünschen des Kunden.

Kapitel 10: Beispiel für die Entwicklung von adaptivem Code: Einführung

Dieses erste Kapitel beschreibt die Anwendung, die entwickelt werden soll: eine Online-Chat-Anwendung, die mit ASP.NET-MVC 5 entwickelt wird. Ein knapper Entwurf zeigt die geplante Architektur, außerdem werden die Features im Backlog erläutert.

Kapitel 11: Beispiel für die Entwicklung von adaptivem Code: Sprint 1

Unter Anwendung eines testorientierten Entwicklungsansatzes werden die ersten Features der Anwendung entwickelt, darunter das Anzeigen und Erstellen von Chaträumen und Nachrichten.

Kapitel 12: Beispiel für die Entwicklung von adaptivem Code: Sprint 2

Natürlich hat der Kunde einige Änderungen an den Anforderungen der Anwendung gemacht und das Team ist in der Lage, diese Änderungswünsche zu erfüllen, weil es adaptiven Code geschrieben hat.

Anhänge

In den Anhängen finden Sie einige Referenzinformationen, konkret eine Anleitung für die Arbeit mit der Quellcodeverwaltung Git und eine Erklärung, wie der Code für dieses Buch auf GitHub organisiert ist.

Anhang A: Adaptive Tools

Dies ist eine knappe Einführung in die Quellcodeverwaltung Git, die Sie zumindest in die Lage versetzen sollte, den Code von GitHub herunterzuladen und ihn in Microsoft Visual Studio 2013 zu kompilieren. Dies soll kein ausführliches Git-Handbuch sein – für diesen Zweck gibt es bereits hervorragende Informationsquellen, zum Beispiel das offizielle Git-Tutorial unter http://git-scm.com/docs/gittutorial. Mit einer Suchmaschine finden Sie bei Bedarf viele andere Quellen. Außerdem stellt dieser Anhang kurz einige andere Entwicklertools vor, zum Beispiel kontinuierliche Integration.

Anhang B (nur online und in englischer Sprache): GitHub-Codebeispiele

Indem ich den Code für dieses Buch auf GitHub bereitstelle, kann ich Änderungen an einer zentralen Stelle vornehmen. Das Repository ist schreibgeschützt, aber die Anhänge A und B verraten Ihnen, wie Sie den Code für ein Listing finden, herunterladen, kompilieren, ausführen und lokal verändern können. Wenn Sie denken, Sie haben einen Fehler gefunden, oder eine Änderung vorschlagen wollen, können Sie ein Pull-Request für das Repository schicken; ich sehe es mir gerne an. Anhang B finden Sie unter microsoftpressstore.com auf der Seite zu diesem Buch.

Konventionen in diesem Buch

In diesem Buch werden besondere Textelemente durch verschiedene Konventionen hervorgehoben. Wenn Sie bereits andere Bücher von Microsoft Press gelesen haben, sind Sie vermutlich damit vertraut. Falls nicht, können Sie sich in diesem Abschnitt darüber informieren.

Codelistings

Dieses Buch enthält zahlreiche Codelistings, deren Bedeutung kurz in einer Listingunterschrift erklärt wird (Listing 0–1).

public void MyService : IService{}

List. 0–1 Dies ist ein Codelisting. Sie finden etliche davon im Buch.

Wenn Ihre Aufmerksamkeit auf einen bestimmten Teil des Codes gelenkt werden soll, weil zum Beispiel Änderungen gegenüber dem vorherigen Beispiel vorgenommen wurden, sind die entsprechenden Abschnitte fett hervorgehoben.

Hinweise und Textkästen

Hinweiskästen werden für kurze Anmerkungen und Hinweise verwendet, während Textkästen umfangreichere Themen behandeln. Hier einige Beispiele:

HINWEIS

Dies ist ein Hinweiskasten. Er enthält kurze Informationsbröckchen, die sich auf den Inhalt beziehen, aber besonders wichtig sind.

Dies ist ein Textkasten

Dieser Textkasten ist zwar relativ kurz, aber meist enthalten sie längere Beiträge zu Themen, die leicht vom Hauptthema abschweifen.

Systemvoraussetzungen

Sie brauchen die folgende Hardware und Software, um die Codebeispiele in diesem Buch zu verwenden:

Windows XP Service Pack 3 (außer Starter Edition), Windows Vista Service Pack 2 (außer Starter Edition), Windows 7, Windows Server 2003 Service Pack 2, Windows Server 2003 R2, Windows Server 2008 Service Pack 2 oder Windows Server 2008 R2

Visual Studio 2013, beliebige Edition (falls Sie Express Edition-Produkte verwenden, sind unter Umständen mehrere Downloads erforderlich)

Microsoft SQL Server 2008 Express Edition oder höher (2008 oder R2 Release), mit SQL Server Management Studio 2008 Express oder höher (enthalten in Visual Studio; für Express Editions ist ein separater Download erforderlich)

Computer mit einem Prozessor mit mindestens 1,6 GHz (2 GHz empfohlen)

1 GByte (bei einer 32-Bit-Version) oder 2 GByte (bei einer 64-Bit-Version) RAM (weitere 512 MByte, falls Sie einen virtuellen Computer verwenden oder SQL Server Express Editions einsetzen, mehr bei leistungsfähigeren SQL Server-Editionen)

3,5 GByte freier Festplattenplatz

Festplattenlaufwerk mit 5.400 U/min

DirectX 9-fähige Grafikkarte an einem Monitor mit mindestens 1024 x 768 Pixel Auflösung

DVD-ROM-Laufwerk (falls Sie Visual Studio von DVD installieren)

Internetverbindung zum Herunterladen von Software und Codebeispielen

Abhängig von Ihrer Windows-Konfiguration benötigen Sie unter Umständen Administratorrechte, um Visual Studio 2013 und SQL Server 2008-Produkte zu installieren oder zu konfigurieren.

Downloads: Codebeispiele

Soweit möglich, habe ich sichergestellt, dass die Codelistings aus einem größeren Beispiel stammen, das entweder als eigenständige Anwendung oder als Unit-Test ausgeführt werden kann. Viele der einfacheren Unit-Tests habe ich mit MSTest geschrieben, daher wird kein externer Test-Runner dafür benötigt, aber für die komplexeren Unit-Tests habe ich auf NUnit zurückgegriffen. Den gesamten Code habe ich in Visual Studio 2013 Ultimate geschrieben. Einige Lösungen habe ich mithilfe der Preview-Version erstellt, aber sie wurden alle unter der fertigen Version kompiliert und getestet. Nach Möglichkeit habe ich keine Features verwendet, die in den Express Editions von Visual Studio 2013 nicht verfügbar sind, aber bei manchen Themen war das nicht möglich. Leser, die diesen Code ausführen wollen, müssen eine kommerzielle Version dafür installieren.

Der Code selbst steht auf GitHub unter der folgenden Adresse zur Verfügung:

http://aka.ms/AdaptiveCode_CodeSamples

Anhang A enthält eine Anleitung zur Benutzung von Git, während Anhang B (nur online) auflistet, in welchen Unterordnern des Git-Repositorys Sie die Listings aus den einzelnen Kapiteln finden.

Wenn Sie eine Anmerkung zum Code haben, können Sie mir in meinem Blog eine Nachricht hinterlassen:

http://garymcleanhall.wordpress.com

Danksagungen

Der Autorenname im Impressum vermittelt einen falschen Eindruck. Ich wäre nie in der Lage gewesen, dieses Buch ohne die folgenden Personen zu schreiben, die mir auf unterschiedliche Weise geholfen haben. Ich möchte danken:

Victoria, meiner Frau, dafür, dass sie dieses Buch möglich gemacht hat. Das ist keine leere Floskel, sondern die reine Wahrheit.

Amelia, meiner Tochter, dafür, dass sie in jeder Hinsicht perfekt ist.

Pam, meiner Mutter, dafür, dass sie korrekturgelesen und mich mit wundervoll übertriebenem Lob angespornt hat.

Les, meinem Vater, für all seine harte Arbeit.

Darryn, meinem Bruder, für seine unermüdliche Hilfe und Unterstützung.

Kathy Krause bei Online Training Solutions, für ihre hervorragende Arbeit, die dieses Buch lesbar gemacht hat.

Devon Musgrave, für seine anscheinend grenzenlose Geduld.

Errata und Support

Wir haben uns sehr um die Richtigkeit der in diesem Buch enthaltenen Informationen bemüht. Fehler, die seit der Veröffentlichung bekannt geworden sind, werden auf der Microsoft Press-Website (in englischer Sprache) aufgelistet:

http://aka.ms/Adaptive/errata

Sollten Sie einen Fehler finden, der noch nicht aufgeführt ist, würden wir uns freuen, wenn Sie uns auf der gleichen Seite darüber informieren (in englischer Sprache).

Mit Anmerkungen, Fragen oder Verbesserungsvorschlägen zu diesem Buch können Sie sich auch an den dpunkt.verlag wenden:

[email protected]

Bitte beachten Sie, dass über unsere E-Mail-Adresse kein Software-Support angeboten wird.

Für Supportinformationen bezüglich der hier verwendeten Microsoft-Produkte besuchen Sie die Microsoft-Website http://support.microsoft.com.

Kostenlose E-Books von Microsoft Press

Von technischen Einführungen bis zu detaillierten Informationen über Spezialthemen decken die nur in Englisch verfügbaren kostenlosen E-Books von Microsoft Press eine große Themenbandbreite ab. Diese E-Books stehen in den Formaten PDF, EPUB und Mobi für Kindle zur Verfügung. Sie können sie herunterladen unter:

http://aka.ms/mspressfree

Schauen Sie ab und zu vorbei, um sich zu informieren, was es Neues gibt!

Teil I

Eine agile Grundlage

KAPITEL 1 Einführung in Scrum

KAPITEL 2 Abhängigkeiten und Schichten

KAPITEL 3 Schnittstellen und Entwurfs-Patterns

KAPITEL 4 Unit-Tests und Refaktorierung

Dieser Teil des Buchs führt in die Grundlagen von agilen Prinzipien und Verfahren ein.

Das Schreiben von Code ist ein Grundpfeiler der Softwareentwicklung. Allerdings gibt es viele unterschiedliche Wege, lauffähigen Code zu erhalten. Selbst wenn Sie die Auswahl von Plattform, Sprache und Framework außen vor lassen, steht ein Entwickler sogar beim Implementieren simpelster Funktionen vor einer Vielzahl von Entscheidungen.

Die Erstellung erfolgreicher Softwareprodukte ist schon immer das primäre Ziel der Softwareentwicklungsbranche. In den letzten Jahren haben sich Entwickler darauf verlegt, Patterns (Muster) und Verfahren zu implementieren, die reproduzierbar sind und sich positiv auf die Codequalität auswirken. Dies ist notwendig geworden, weil sich die Codequalität nicht mehr von der Qualität des fertigen Softwareprodukts trennen lässt. Im Lauf der Zeit wird minderwertiger Code die Qualität des Produkts herunterziehen, zumindest wird er die Auslieferung funktionierender Software verzögern.

Um qualitativ hochwertige Software zu produzieren, müssen Entwickler sicherstellen, dass ihr Code gut wartbar, einfach zu lesen und vollständig getestet ist. Daneben hat sich als neue Anforderung herauskristallisiert, dass Code adaptiv, also anpassungsfähig sein sollte.

Die Kapitel in diesem ersten Buchteil stellen moderne Softwareentwicklungsprozesse und -verfahren vor. Diese Prozesse und Verfahren werden zusammenfassend als agile Prozesse und Verfahren bezeichnet, womit betont werden soll, dass sich ihre Richtung schnell ändern kann. Agile Prozesse stellen Möglichkeiten bereit, wie ein Softwareentwicklungsteam schnelles Feedback erhalten und als Reaktion darauf seinen Fokus verschieben kann. Agile Verfahren bieten dagegen Wege, wie ein Softwareentwicklungsteam Code schreibt, der bei Bedarf eine neue Richtung einschlagen kann.

Kapitel 1

Einführung in Scrum

Am Ende dieses Kapitels werden Sie in der Lage sein, die folgenden Aufgaben durchzuführen:

Zuweisen von Rollen an die wichtigsten Stakeholder des Projekts

Beschreiben der unterschiedlichen Dokumente und anderer Artefakte, die Scrum benötigt und produziert

Messen des Fortschritts eines Scrum-Projekts im Lauf seiner Entwicklung

Diagnostizieren von Problemen bei Scrum-Projekten und Vorschlagen von Gegenmitteln

Abhalten von produktiven Scrum-Meetings, die allen Beteiligten nützen

Begründen, warum Scrum und nicht andere agile oder rigide Methodologien eingesetzt werden

Scrum ist eine Methodologie für die Projektverwaltung. Genauer gesagt handelt es sich um eine agile Methodologie. Das zentrale Konzept von Scrum beruht darauf, den Nutzen eines Softwareprodukts iterativ, also phasenweise, zu steigern. Der gesamte Scrum-Prozess wird mehrmals wiederholt (die Iterationen), bis das Softwareprodukt als vollständig beurteilt oder der Prozess abgebrochen wird. Diese Iterationen werden als Sprints bezeichnet. Sie münden in einer Software, die als fertiges Produkt freigegeben werden kann. Die gesamte Arbeit wird im sogenannten Produkt-Backlog (Produkt-Rückstand) in Prioritäten eingestuft, und bei Beginn jedes Sprints legt das Entwicklungsteam fest, welche Arbeiten es in der aktuellen Iteration erledigen wird, indem es diese Arbeiten im Sprint-Backlog festhält. Eine Arbeitseinheit innerhalb von Scrum wird als Story (Geschichte) bezeichnet. Das Produkt-Backlog ist eine nach Prioritäten sortierte Liste abzuarbeitender Stories, und jeder Sprint wird durch die Stories definiert, die während einer Iteration entwickelt werden. Abbildung 1–1 zeigt einen Überblick des Scrum-Prozesses.

Abb. 1–1 Scrum ähnelt einer Fertigungsstraße für kleine Features eines Softwareprodukts

Scrum umfasst verschiedene Dokumentationsartefakte, Rollen, die von Personen innerhalb und außerhalb des Entwicklungsteams übernommen werden, und Zeremonien, das heißt Meetings, an denen die relevanten Gruppen teilnehmen. Ein einziges Kapitel reicht nicht aus, um alle Vorteile von Scrum als Projektverwaltungsmethode aufzuzeigen, aber dieses Kapitel sollte Ihnen einen ausreichenden Überblick vermitteln, damit Sie sich bei Bedarf tiefer in bestimmte Teilbereiche einarbeiten können und die Bedeutung der üblichen Scrum-Verfahren durchblicken.

Scrum ist agil

Unter dem Begriff agil (engl. agile) wird eine Familie schlanker Softwareentwicklungs-methoden zusammengefasst, die es ermöglichen, auf geänderte Anforderungen der Kunden auch dann noch zu reagieren, wenn das Projekt bereits läuft. Agile Methoden sind die Antwort auf die Nachteile von Verfahren, die rigider strukturiert sind. Das Agile-Manifest macht diesen Gegensatz deutlich, Sie finden es unter www.agilemanifesto.org.

Das Agile-Manifest wurde von 17 Softwareentwicklern unterzeichnet. Die Agile-Methode hat in den letzten Jahren so stark an Einfluss gewonnen, dass Erfahrung in einer agilen Umgebung zur unverzichtbaren Voraussetzung für einen Posten im Rahmen der Softwareentwicklung geworden ist. Scrum ist eine der am häufigsten genutzten Implementierungen eines agilen Prozesses.

Scrum und Wasserfall

Ich habe die Erfahrung gemacht, dass in der Softwareentwicklung der agile Ansatz besser funktioniert als das Wasserfallmodell (engl. waterfall), daher empfehle ich grundsätzlich nur agile Prozesse. Das Problem bei der Wasserfallmethode ist ihre Inflexibilität. Abbildung 1–2 zeigt die Abläufe bei einem Wasserfallprojekt.

Abb. 1–2 Der Entwicklungsprozess bei der Wasserfallmethode

Die Ergebnisse jeder Phase werden dabei zur Basis der nächsten Phase, und jede Phase wird vollständig abgeschlossen, bevor die nächste in Angriff genommen wird. Das setzt voraus, dass keine Fehler, Probleme, ungelösten Fragen oder Missverständnisse mehr auftauchen, nachdem eine Phase abgeschlossen ist. Die Pfeile zeigen nur in eine Richtung.

Der Wasserfallprozess geht außerdem davon aus, dass nach Abschluss einer Phase keine Änderungen mehr vorgenommen werden. Diese Annahme lässt sich angesichts der eigenen Erfahrung und zahlreicher Untersuchungen einfach nicht aufrechterhalten. Änderungen gehören einfach zum Leben dazu, nicht nur bei der Softwareentwicklung. Wasserfallansätze behandeln Änderungen als etwas, das teuer und unerwünscht ist und daher unbedingt vermieden werden sollte. Wasserfallmethoden basieren auf dem Konzept, dass sich Änderungen vermeiden lassen, wenn man mehr Zeit auf die Ausarbeitung von Anforderungen und Entwurf verwendet. In diesem Denkkonzept tauchen Änderungen während der nachfolgenden Phasen schlicht nicht auf. Das ist natürlich lächerlich, weil sich immer Änderungen ergeben.

Das Agile-Konzept begegnet diesem Problem, indem es einen fundamental anderen Ansatz verwendet, in dem Änderungen als etwas Positives betrachtet werden und jeder die Gelegenheit erhält, sich an alle auftretenden Änderungen anzupassen. Das Agile-Konzept und somit auch Scrum lassen zwar Änderungen auf Prozessebene zu, aber auf das Ziel künftiger Änderungen hin zu programmieren ist eine der schwierigsten und gleichzeitig wichtigsten Ziele moderner Softwareentwicklung. Dieses Buch will Ihnen zeigen, wie Sie Code erstellen, der so agil und adaptiv ist, dass er Änderungen übersteht.

Wasserfallmethodologien sind außerdem dokumentzentriert, das heißt, sie produzieren große Mengen an Dokumentation, die nicht direkt das Softwareprodukt verbessert. Bei den Agile-Methoden wird dagegen die lauffähige Software als wichtigstes Dokument eines Softwareprodukts betrachtet. Das Verhalten der Software wird schließlich durch ihren Quellcode gesteuert, nicht durch die Dokumente, die begleitend zum Code verfasst wurden. Und weil die Dokumentation vom Quellcode getrennt ist, kann es leicht passieren, dass sie nicht mehr mit der Software übereinstimmt.

Scrum definiert einige Kennzahlen, die Rückmeldungen zum Fortschritt eines Projekts und seinem Gesamtzustand liefern, aber das ist etwas anderes als eine erklärende Dokumentation über das Produkt. Agile-Methoden empfehlen im Allgemeinen, nur so viel Dokumentation zu produzieren, dass das Projekt nicht ins Unverantwortliche abkippt, aber sie schreiben eine solche Dokumentation meist nicht vor. Es gibt durchaus Code, der von ergänzender Dokumentation profitiert, sofern sie nicht einmal geschrieben und dann nie wieder gelesen wird. Aus diesem Grund sind lebendige, einfach zu nutzende Dokumente, wie beispielsweise Wikis, wichtige Werkzeuge in Scrum-Teams.

Der Rest dieses Kapitels behandelt die wichtigsten Aspekte von Scrum genauer. Dabei konzentrieren wir uns nicht auf pures Scrum, sondern auf eine beliebte Variante. Das Ziel von Scrum als Prozess besteht nicht nur darin, das Softwareprodukt iterativ zu verbessern, sondern auch den Entwicklungsprozess. Das animiert die Teams, kleine Änderungen vorzunehmen und so dafür zu sorgen, dass sich der Prozess optimal für ihre konkrete Situation eignet.

Nachdem die folgenden Abschnitte die Elemente von Scrum vorgestellt haben, analysiert der Rest des Kapitels ihre Schwächen. Dieses Kapitel bildet die Basis für das übrige Buch, das genauer ausführt, wie Sie Code so implementieren, dass er adaptiv ist und somit Änderungen ermöglicht, die im Scrum-Prozess als etwas Positives aufgefasst werden. Es wäre sinnlos, einen Prozess zu nutzen, in dem Sie den Anspruch erheben, Änderungen problemlos implementieren zu können, wenn in Wirklichkeit jegliche Änderung auf Codeebene unglaublich schwierig zu implementieren ist.

Unterschiedliche Formen von Scrum

Wenn ein Entwicklungsteam behauptet, eine Scrum-Methodologie umzusetzen, heißt das meist, dass sie eine Variante von Scrum einsetzen. Pures Scrum umfasst nur wenige Verfahren, die aus anderen Agile-Methoden übernommen wurden, zum Beispiel Extreme Programming (XP). Es gibt drei Unterkategorien von Scrum, die sich jeweils weiter von der reinen Lehre entfernen.

Scrum und …

Verfahrensempfehlungen wie die, zuerst die Unit-Tests zu schreiben und paarweise zu programmieren, sind nicht Bestandteil von Scrum. Viele Teams betrachten sie aber als nützliche Ergänzungen des Prozesses, daher werden sie oft als ergänzende Verfahren übernommen. Werden bestimmte Verfahren aus anderen Agile-Methoden wie XP oder Kanban übernommen, wird der Prozess zu »Scrum und …« (engl. »Scrum and«), das heißt: Scrum plus zusätzliche Verfahren, die den Scrum-Standardprozess erweitern, aber nicht beeinträchtigen.

Scrum, aber …

Manche Entwicklungsteams behaupten zwar, Scrum einzusetzen, lassen aber Kernaspekte außen vor. Ihre Arbeit wird durch ein Backlog bestimmt, das in iterative Sprints eingeht, und sie halten Retrospectives und tägliche Stand-Up-Meetings ab. Aber sie nehmen keine Einstufung in Story-Punkte vor, sondern bevorzugen Echtzeiteinstufungen. Solche verwässerten Versionen von Scrum werden mit »Scrum, aber …« (engl. »Scrum but«) bezeichnet. Das Team hält sich in vielen Bereichen an Scrum, weicht aber in einem oder zwei Kernbereichen davon ab.

Nicht Scrum …

Wenn sich ein Entwicklungsteam weit genug von der Scrum-Methode entfernt, landet es bei »Nicht Scrum …« (engl. »Scrum not«). Das verursacht Probleme, besonders wenn Teammitglieder eine Agile-Methodologie erwarten, aber der tatsächlich genutzte Prozess sich davon so stark unterscheidet, dass er höchstens noch oberflächliche Ähnlichkeit zu Scrum aufweist. Ich finde, dass das tägliche Stand-Up-Meeting das am einfachsten umzusetzende Scrum-Element ist, aber relative Aufwandsschätzung und die positive Einstellung gegenüber Änderungen sind deutlich schwieriger. Wenn genug Elemente des Scrum-Prozesses weggelassen werden, handelt es sich bei diesem Prozess nicht mehr um Scrum.

Rollen und Verantwortungsbereiche

Scrum ist lediglich ein Prozess, der nur in dem Maß nutzbringend ist, wie die Beteiligten dem Prozess folgen. Diese Beteiligten übernehmen Rollen und Verantwortungsbereiche, die dann ihre Aktivitäten bestimmen.

Product Owner

Der Product Owner (»Produktbesitzer«, oft als PO abgekürzt) ist eine zentrale Rolle. Er ist der Mittler zwischen dem Abnehmer oder Kunden und dem Rest des Entwicklungsteams. Product Owner nehmen das fertige Produkt in Besitz, daher fallen ihnen die folgenden Verantwortungsbereiche zu:

Entscheiden, welche Features verwirklicht werden

Festlegen, welche Priorität die Features abhängig von ihrem wirtschaftlichen Wert erhalten

Annehmen oder Zurückweisen von »fertiger« Arbeit

Als ein zentraler Stakeholder, der den Erfolg des Projekts entscheidend mitbestimmt, muss der PO dem Team zur Verfügung stehen und in der Lage sein, die Vision verständlich zu kommunizieren. Dem Entwicklungsteam sollte das langfristige Ziel des Projekts klar sein, wobei ein Kurswechsel bei der Projektausrichtung dem gesamten Team möglichst bald vermittelt werden sollte. Bei der kurzfristigen Sprintplanung legt der Product Owner dar, was wann entwickelt wird. Der Product Owner entscheidet, welche Features im Verlauf des Projekts benötigt werden, um die Software freigeben zu können, und er legt die Prioritäten für das Produkt-Backlog fest.

Die Rolle des Product Owners ist zwar sehr wichtig, er hat aber keine uneingeschränkte Macht über den Prozess. Der Product Owner hat keinen Einfluss darauf, zu welchem Arbeitsumfang sich das Team in einem Sprint verpflichtet, weil dies vom Team selbst abhängig von seiner Geschwindigkeit festgelegt wird. Product Owner schreiben auch nicht vor, wie die Arbeit erledigt wird; das Entwicklungsteam behält die Kontrolle darüber, wie es eine bestimmte Story auf technischer Ebene implementiert. Sobald ein Sprint begonnen wurde, kann der Product Owner nicht mehr dessen Ziele ändern, andere Akzeptanzkriterien festlegen oder Stories hinzufügen oder entfernen. Nachdem im Rahmen der Sprintplanung einmal die Ziele und die Stories festgelegt wurden, darf der laufende Sprint nicht mehr geändert werden. Jegliche Änderungen müssen bis zum nächsten Sprint warten – sofern die Änderung nicht darin besteht, den Sprint oder das gesamte Projekt abzubrechen und von vorn zu beginnen. So kann sich das Entwicklungsteam ganz darauf konzentrieren, die Sprintziele zu erreichen, ohne dass die Ziellinie verschoben wird.

Während sich im Verlauf des Sprints die Stories entwickeln und fertiggestellt werden, wird der Product Owner aufgefordert, zu prüfen, ob ein Feature funktioniert, oder eine bearbeitete Aufgabe zu kommentieren. Es ist wichtig, dass Product Owner während des Sprints eine gewisse Zeit dafür reservieren, mit dem Entwicklungsteam zu kommunizieren und für den Fall zur Verfügung zu stehen, dass etwas Unerwartetes passiert und Unklarheiten auftreten. So wird vermieden, dass der Product Owner am Ende des Sprints »fertige« Stories vorgesetzt bekommt, die seiner ursprünglichen Vorstellung widersprechen. Dem Product Owner fällt allerdings die Entscheidung zu, ob eine Story die vereinbarten Akzeptanzkriterien erfüllt und ob sie als vollständig eingestuft und am Ende des Sprints vorgeführt werden kann.

Scrum Master

Der Scrum Master (kurz SM) schirmt das Team von allen externen Ablenkungen ab, während ein Sprint läuft, und beseitigt alle Hindernisse, die das Team im täglichen Scrum-Meeting anspricht. So hält er das Team während des gesamten Sprints arbeitsfähig und produktiv, sodass es sich voll und ganz auf die Sprint-Ziele konzentrieren kann.

Ähnlich wie der Product Owner das Produkt (was erledigt werden muss) besitzt, ist der Scrum Master der Besitzer des Prozesses (des Rahmens, mit dem festgelegt wird, wie die Aufgabe erledigt wird). Daher muss der Scrum Master sicherstellen, dass das Team dem Prozess folgt. Der Scrum Master kann Vorschläge machen, wie der Prozess verbessert werden könnte (zum Beispiel durch Umstellung von einem vierwöchigen Sprint auf einen zweiwöchigen), aber sein Einfluss ist begrenzt. Ein Scrum Master kann beispielsweise nicht anordnen, auf welche Weise das Team eine Story implementiert, er darf lediglich sicherstellen, dass das Team sich an den Scrum-Prozess hält.

Als Besitzer des Prozesses ist ein Scrum Master auch der Verantwortliche für das tägliche Scrum-Meeting, den sogenannten Daily Scrum. Der Scrum Master sorgt dafür, dass das Team teilnimmt und führt ein Protokoll für den Fall, dass Punkte angesprochen werden, die eine Reaktion erfordern. Das Team legt während des Scrum-Meetings aber nicht gegenüber dem Scrum Master Rechenschaft ab, vielmehr informieren die Teammitglieder alle über ihre Fortschritte.

Entwicklungsteam

Im Idealfall besteht ein Agile-Team aus universellen Spezialisten. Das bedeutet, dass jedes Teammitglied interdisziplinär ist, also mit mehreren unterschiedlichen Technologien umgehen kann, aber besondere Fähigkeiten, Vorlieben oder Spezialisierung für einen bestimmten Bereich hat. Zum Beispiel könnte ein Team aus vier Entwicklern bestehen, die alle hochkompetent mit ASP.NET-MVC, Windows Workflow und Windows Communication Foundation (WCF) arbeiten können. Zwei dieser Entwickler sind auf Windows Forms spezialisiert, die beiden anderen arbeiten lieber mit Windows Presentation Foundation (WPF) und Microsoft SQL Server.

Ein universelles Team beugt Problemen vor, bei denen ein Mitarbeiter, die »Web-Person«, die »Datenbank-Person« oder die »WPF-Person«, als Einziger weiß, wie ein bestimmter Teil der Anwendung funktioniert. Solche Situationen sind für alle Beteiligten problematisch, daher sollte mit allen Mitteln versucht werden, sie von vornherein zu vermeiden. In Scrum ist das gesamte Team Besitzer des Codes. Spezialistentum ist schlecht für ein Unternehmen, weil der wirtschaftliche Erfolg in einem bestimmten Bereich zu stark von einem einzelnen Mitarbeiter abhängt. Und auch dieser Mitarbeiter leidet unter der Situation, weil er ständig in Rollen gedrängt wird, die »nur er beherrscht«.

Softwaretester müssen die Qualität der Software sicherstellen, während sie entwickelt wird. Bevor eine Story in Angriff genommen wird, können die Tester automatisierte Testpläne diskutieren, mit denen geprüft wird, ob die Implementierung einer Story alle Akzeptanzkriterien erfüllt. Sie arbeiten dazu oft mit den Entwicklern zusammen, um die Testpläne zu implementieren, manchmal schreiben sie solche Tests auch selbst. Sobald eine Story implementiert ist, liefern die Entwickler sie zum Testen ab, woraufhin der Testanalyst prüft, ob sie wie gefordert funktioniert.

Schweine und Hühner

Jede Rolle im Scrum-Prozess kann in die Kategorie »Schwein« (engl. pig) oder »Huhn« (engl. chicken) eingestuft werden. Diese Zuordnung bezieht sich auf die folgende Geschichte: Ein Huhn besucht seinen Freund, das Schwein, und sagt: »Hallo Schwein, ich habe eine Idee. Ich denke, wir sollten ein Restaurant eröffnen!« Zuerst ist das Schwein ganz begeistert und fragt: »Wie sollen wir es nennen?« Das Huhn erwidert: »Nennen wir es Schinken- und Eierpalast.« Das Schwein denkt ein wenig darüber nach und schreit dann wütend: »Niemals! Ich würde mich voll einsetzen, aber du würdest nur beitragen!«

Diese Fabel macht deutlich, in welchem Maß sich bestimmte Mitglieder in einem Projekt engagieren müssen. Schweine sind einem Projekt vollständig verpflichtet und werden für seinen Ausgang verantwortlich gemacht, während Hühner lediglich dazu beitragen und eher peripher damit zu tun haben. Der Product Owner, der Scrum Master und das Entwicklungsteam sind in diesem Kontext alle Schweine, weil sie sich mit aller Kraft dafür einsetzen, das Produkt abzuliefern. Kunden sind dagegen oft nur Hühner, die lediglich zum Projekt beitragen. Auch die Unternehmensleitung trägt nur zum Projekt bei und ist als Huhn einzustufen, nicht als Schwein.

Artefakte

Über die Lebensdauer jedes Softwareprojekts hinweg werden viele Dokumente, Grafiken, Diagramme, Tabellen und Kennzahlen erstellt, geprüft, analysiert und auseinandergenommen. Das ist bei einem Scrum-Projekt nicht anders. Allerdings unterscheiden sich Scrum-Dokumente von Dokumenten anderer Projektverwaltungsmethoden durch ihren Typ und ihren Zweck. Ein Hauptunterschied zwischen allen agilen Prozessen und den inflexibleren Prozessen ist die relative Bedeutung der Dokumentation. SSADM (Structured Systems Analysis and Design Methodology) legt zum Beispiel großen Wert darauf, viel Dokumentation zu schreiben. Dies wird abwertend als BDUF (Big Design Up Front, »großer Entwurf im Vorfeld«) bezeichnet: der Trugschluss, dass sich jegliche Furcht, jede Unsicherheit und aller Zweifel in einem Projekt vermeiden lässt, wenn nur genug Aufwand in die Dokumentation gesteckt wird. Agile Prozesse streben danach, den Umfang der produzierten Dokumentation auf das zu verringern, was für den Erfolg des Projekts wirklich unverzichtbar ist. Stattdessen vertreten Agile-Methoden den Ansatz, dass der Code (der die maßgebliche Dokumentation schlechthin ist) jederzeit bereitgestellt, ausgeführt und benutzt werden kann. Außerdem sollen alle Stakeholder direkt miteinander kommunizieren, statt Dokumente zu schreiben, die von ihren wichtigsten Adressaten niemals gelesen werden. Dokumentation ist auch in einem Agile-Projekt wichtig, aber sie hat keine höhere Bedeutung als lauffähige Software oder Kommunikation.

Das Scrum-Board

Einen Mittelpunkt der täglichen Arbeit in einem Scrum-Projekt bildet das Scrum-Board (Scrum-Tafel). Für das Scrum-Board sollte eine großzügig bemessene Wandfläche reserviert sein. Ist die Tafel zu klein, verleitet das womöglich dazu, wichtige Details wegzulassen. Falls in Ihrem Büro die Wandfläche knapp ist, können Sie einige Tricks anwenden. Vielleicht lässt sich das große, kaum genutzte Whiteboard zum Scrum-Board umfunktionieren. Mithilfe von Magneten lassen sich Stahlschränke in ein Scrum-Board verwandeln. Falls Ihr Büro angemietet ist oder Sie aus einem anderen Grund keine Löcher in die Wand bohren können, sind ausziehbare, abwischbare Rollladentafeln ideal. Versuchen Sie, in Ihrem Büro einen geeigneten Platz für diesen Zweck zu finden. Unabhängig davon, wie es aussieht und wie Sie es nennen, können Sie es natürlich verändern, falls es sich nach einigen Iterationen nicht richtig anfühlt. Scrum-Boards, die man tatsächlich anfassen kann, sind unverzichtbar. Nichts kann das Bauchgefühl ersetzen, das Sie erleben, wenn Sie vor einem Scrum-Board stehen. Digitale Scrum-Werkzeuge haben ihre Berechtigung, aber ich denke, sie sollten im Scrum-Prozess lediglich als Ergänzung dienen, niemals als zentrales Element. Abbildung 1–3 zeigt ein typisches Scrum-Board.

Abb. 1–3 Scrum-Board gibt den momentanen Zustand des aktuell entwickelten Projekts wieder

Ein Scrum-Board enthält eine Vielzahl von Informationen. Es liefert etliche Details, daher kann es anfangs schwierig wirken, die gewünschten Informationen zu finden. Die nächsten Abschnitte erklären die einzelnen Elemente genauer.

Karten

Die Hauptelemente des Scrum-Boards sind die Karten. Sie stehen für unterschiedliche Elemente, die den Fortschritt eines Softwareprodukts vorantreiben. Das kann von einem Release der Software bis zu winzigsten Einzelaufgaben reichen. Für jeden Kartentyp wird normalerweise eine andere Farbe verwendet, um die Übersichtlichkeit zu erhöhen. Aufgrund des beschränkten Platzes zeigt das Scrum-Board normalerweise nur die Stories, Aufgaben, Fehler und Technical Debts (»technische Schulden«), die mit dem aktuellen Sprint verknüpft sind.

HINWEIS

Unter Umständen können nicht alle Teammitglieder die Farben der Karten unterscheiden. Sie können die Farben zusätzlich mit unterschiedlichen Formen kombinieren, damit auch farbenblinde Teammitglieder den Kartentyp erkennen.

Hierarchie

Abbildung 1–4 zeigt die Beziehungen der Karten auf einem Scrum-Board. Dabei wird angenommen, dass ein Produkt sich aus vielen Tasks (Aufgaben) zusammensetzt. Sogar eine hochkomplexe Software kann sich in eine endliche Liste von Einzeltasks untergliedern lassen, die ausgeführt werden müssen, um das Produkt fertigzustellen.

Abb. 1–4 Die Karten auf dem Scrum-Board repräsentieren unterschiedliche Teile eines Gesamtprodukts

Produkt

Ganz oben in der Scrum-Hierarchie steht das Softwareprodukt (engl. product), das erstellt werden soll. Beispiele für Produkte sind fast endlos: integrierte Entwicklungsumgebungen, Webanwendungen, Buchhaltungssoftware, Social-Media-Apps und vieles andere. Dies ist die Software, die Sie entwickeln, und das Produkt, das Sie abliefern wollen.

Teams arbeiten normalerweise nur an einem einzigen Produkt gleichzeitig, aber gelegentlich kommt es vor, dass Teams auch mehrere Produkte liefern müssen.

Release

Zu jedem Produkt, das Sie entwickeln, gibt es mehrere Releases. Ein Release ist eine Version der Software, die Endbenutzer kaufen oder einsetzen können. Manchmal wird ein Release nur erstellt, um Fehler zu beseitigen, aber ein Release kann auch wertvolle neue Features für wichtige Kunden hinzufügen oder eine Betaversion der Software zum Ausprobieren verfügbar machen.

Webanwendungen haben oft eine implizite Version, wobei es nur eine einzige Bereitstellung gibt, die alle älteren Releases ersetzt. Der Webbrowser Google Chrome ist ein interessantes Beispiel. Es handelt sich zwar um eine Desktopanwendung, er wird aber als Stream von Mikro-Releases bereitgestellt, die nahtlos auf Desktops bereitgestellt werden, und das ganz ohne großartige Ankündigungen wie bei den Browsern der Konkurrenz. Internet Explorer 8, 9 und 10 wurden jeweils in eigenen Werbespots im Fernsehen angepriesen. Bei Chrome ist das anders: Google bewirbt einfach den Browser, unabhängig von seiner jeweiligen Version. Und solche iterativen Releases verbreiten sich immer weiter. Scrum kann dieses Releasemuster unterstützen, weil es auf das Ziel hinarbeitet, nach jedem Sprint lauffähige Software zu liefern.

MVR

Als erstes Release kann ein MVR (Minimum Viable Release, lauffähiges Minimalrelease) angepeilt werden, bei dem ein grundlegender Funktionsumfang vorhanden ist, der ausreicht, um die Basisanforderungen zu erfüllen. Bei Buchhaltungssoftware könnte sich der Funktionsumfang beispielsweise darauf beschränken, neue Kunden anzulegen, Transaktionen (Ein- und Auszahlungen) zu ihren Konten hinzuzufügen und den Saldo anzuzeigen. Das Konzept besteht dabei darin, das Projekt so weit voranzubringen, dass es sich möglichst bald selbst finanziert. Das ist von einem MVR zwar kaum zu erwarten, aber unter Umständen generiert das MVR wenigstens genug Einnahmen, um die laufenden Entwicklungskosten zu decken. Außerdem bringt diese erste Bereitstellung, sogar wenn sie nur einen beschränkten Kundenkreis erreicht, oft wichtige Rückmeldungen, die die künftige Richtung der Software beeinflusst. Das ist das Kernkonzept von Scrum (und Agile-Methoden generell): das Softwareprodukt ständig weiterzuentwickeln, wobei akzeptiert wird, dass sich jede Software verändert.

Unabhängig vom Zweck des Release oder der Art oder Häufigkeit seiner Bereitstellung wird ein bestimmtes Produkt mehrere Releases überdauern, sofern alles richtig läuft.

Feature

Jedes Release umfasst mindestens ein Feature, das vorher nicht in der Software verwirklicht war. Der deutlichste Unterschied zwischen Version 1.0 und Version 2.0 jeder beliebigen Software sind neu hinzugekommene Features, von denen das Team glaubt, dass sie neue Benutzer zum Kauf und vorhandene Benutzer zum Upgrade motivieren.

Der Begriff MMF (Minimum Marketable Feature, minimal marktreifes Feature) eignet sich gut, um Features zu skizzieren und ein Release zusammenzustellen. Die folgende Liste enthält Beispiele für Features, die so allgemein formuliert sind, dass sie auf viele unterschiedliche Projekte passen, aber auch so konkret, dass sie in konkreten Produkten vorkommen:

Exportieren von Anwendungsdaten in ein portables XML-Format

Ausliefern von Webseitenanforderungen innerhalb von 0,5 Sekunden

Archivieren älterer Daten für künftigen Abruf

Kopieren und Einfügen von Text

Freigeben von Dateien in einem Netzwerk, damit Kollegen darauf Zugriff erhalten

Features sind marktreif, wenn sie für den Kunden einen Wert haben. Wird der Funktionsumfang so weit eingeschränkt, dass er gerade noch seinen Wert behält, handelt es sich um ein minimales Feature.

Epics/Features, MMFs und Themes

Im Kontext von Scrum sind Sie möglicherweise eher mit dem Begriff Epic (Epos) als mit Feature vertraut, aber ich nehme mir die Freiheit, hier meinen bevorzugten Begriff zu verwenden. Epics und Features werden oft als »große Stories« betrachtet, also Stories, die viel umfangreicher als MMFs sind und nicht in einem einzigen Sprint geliefert werden können.

Features ähneln außerdem Scrum-Themes (Themen), weil sie Stories, die einem gemeinsamen Ziel dienen, zu Gruppen zusammenfassen.

Features können für jedes Release grob in drei Kategorien untergliedert werden: nötig (engl. required), bevorzugt (engl. preferred) und gewünscht (engl. desired). Diese Möglichkeiten schließen sich gegenseitig aus. Sie spiegeln wider, welche Priorität jedem Feature zugewiesen ist. Im Allgemeinen ist das Entwicklungsteam gehalten, an allen nötigen Features zu arbeiten, bevor es die bevorzugten Features in Angriff nimmt; an gewünschten Features wird nur gearbeitet, falls Zeit übrig bleibt. Wie Sie bestimmt schon ahnen, können diese Kategorien (und auch die Features selbst) stets geändert werden. Sie können jederzeit eingestellt, in eine andere Priorität eingestuft, verändert und ersetzt werden, woraufhin das Team problemlos umschwenken sollte (vorausgesetzt natürlich, dass Fertigstellungstermine und Budget entsprechend angepasst werden). In Scrum ist nichts in Stein gemeißelt, und dieses Buch soll Ihnen helfen, sich auf diese Tatsache einzustellen.

User Story

Die User Story (»Benutzergeschichte«) ist wahrscheinlich das Scrum-Artefakt, das am meisten Leute kennen, dabei wird es überhaupt nicht von Scrum vorgeschrieben. User Stories sind ein Artefakt aus dem Extreme Programming (XP), wurden aber in Scrum übernommen, weil sie so häufig verwendet werden. User Stories werden anhand des folgenden Schemas festgelegt:

»Als [Benutzerrolle] will ich [tätigkeitsorientiertes Verhalten], damit [Wert für Benutzer hinzugefügt].«

Die eckigen Klammern sind Platzhalter, die ersetzt werden, um unterschiedliche User Stories zu formulieren. Hier ein konkretes Beispiel:

»Als nicht-authentifizierter, aber registrierter Benutzer will ich mein Kennwort zurücksetzen, damit ich mich am System anmelden kann, falls ich mein Kennwort vergessen habe.«

Zu dieser User Story gibt es eine Menge zu sagen. Als Erstes fällt auf, dass sie bei weitem nicht ausführlich genug ist, um das erforderliche Verhalten zu implementieren. Beachten Sie, dass die User Story aus der Perspektive eines Benutzers geschrieben wird. Das sollte zwar selbstverständlich sein, dieser Punkt wird aber oft übersehen, und als Folge werden viele Stories fälschlicherweise aus der Sicht von Entwicklern verfasst. Aus diesem Grund ist der erste Teil der Vorlage, »Als [Benutzerrolle]«, so wichtig. Der Abschnitt [Wert für Benutzer hinzugefügt] ist genauso wichtig, denn ohne ihn gerät leicht in Vergessenheit, warum die User Story überhaupt verfasst wurde. Dieser Abschnitt bindet normalerweise die User Story an ihr übergeordnetes Feature. Das obige Beispiel könnte etwa zu einem Feature wie »Vergessene Benutzeranmeldeinformationen können wiederhergestellt werden« gehören. Die Story stünde in diesem Fall wahrscheinlich zusammen mit den Stories, in denen ein Benutzer seinen Anmeldenamen oder sowohl den Anmeldenamen als auch sein Kennwort vergessen hat.

Wie schon bemerkt, reicht diese User Story nicht aus, um mit der Entwicklung zu beginnen. Welchen Wert hat sie also? Eine User Story steht für ein Gespräch, das später zwischen dem Entwicklungsteam und dem Kunden stattfinden wird. Ist der Zeitpunkt gekommen, die Story zu implementieren, legen die verantwortlichen Entwickler die Story dem Kunden vor und sprechen mit ihm seine Anforderungen durch. Aus dieser Analysephase gehen mehrere Akzeptanzkriterien hervor, die über die gesamte Lebensdauer der User Story hinweg erfüllt werden müssen, damit die User Story als vollständig eingestuft werden kann.

Sobald die Anforderungen zusammengestellt sind, setzen sich die Entwickler zusammen und skizzieren einige Entwurfsideen, mit denen sich diese Anforderungen erfüllen lassen. Manchmal werden in dieser Phase Benutzeroberflächen-Mockups erstellt, etwa mit Balsamiq, Microsoft Visio oder einem anderen Tool. Manche technischen Entwurfskonzepte führen aus, wie die vorhandene Codebasis angepasst werden muss, um die neuen Anforderungen zu erfüllen; dafür werden oft UML-Diagramme (Unified Modeling Language) eingesetzt.

Ist der Entwurf abgesegnet, kann das Team damit beginnen, die User Story in einzelne Tasks zu zerlegen und dann die Story zu implementieren, indem es die Tasks ausführt. Sobald ein Punkt erreicht ist, an dem das Team überzeugt ist, dass die Story wie gefordert funktioniert, kann es sie für Akzeptanztests weiterleiten. Diese abschließende Phase der Qualitätssicherung (Quality Assurance, QA) prüft penibel, ob die Software alle Akzeptanzkriterien erfüllt, und nimmt sie als Ergebnis an oder weist sie zurück. Wurde grünes Licht gegeben, ist die User Story damit abgeschlossen.

Fassen wir den Ablauf noch einmal zusammen: Anhand der User Story als Leitlinie sammeln die Entwickler in einer Analysephase Anforderungen, erstellen einen Entwurf, implementieren eine funktionierende Lösung und testen dann, ob sie die Akzeptanzkriterien erfüllt. Das klingt verdächtig wie Wasserfall-Entwicklungsmethoden! Und tatsächlich ist genau das der Zweck von User Stories: Sie sollen den gesamten Softwareentwicklungszyklus für jede einzelne Story im Miniaturformat durchlaufen. So wird weniger Aufwand verschwendet, weil die User Story zu dem Zeitpunkt, an dem sie vom Scrum-Board gepflückt und implementiert wird, mit Sicherheit noch für das Softwareprodukt relevant ist.

In Scrum konzentriert sich die Arbeit auf User Stories. Sie enthalten die Motivation, die Scrum den Teammitgliedern bereitstellt: Story-Punkte (engl. story points). Während der Sprintplanung weist das Team jeder User Story ihren Story-Punkt-Wert zu, und nach Fertigstellung der User Story werden die Story-Punkte als erworben verbucht und von der Sprintsumme abgezogen. Story-Punkte werden weiter unten in diesem Kapitel genauer beschrieben.

Task

Es gibt eine kleinere Arbeitseinheit als die User Story, den Task (Aufgabe). Stories können in mehrere kleinere Tasks aufgeteilt werden, die dann auf die Entwickler verteilt werden, die für die Story verantwortlich sind. Ich warte meist, bis die Story vom Scrum-Board genommen wird, bevor ich sie in Tasks unterteile, aber manche Teams erledigen das auch schon im Rahmen der Sprintplanung.

User Stories müssen eine vollständige vertikale Funktionseinheit umfassen, Tasks dürfen dagegen an Schichtgrenzen enden, damit die Spezialisierung der Entwickler innerhalb des Teams zum Tragen kommt. Wird zum Beispiel ein neues Feld in einem vorhandenen Formular benötigt, müssen wahrscheinlich Änderungen in den Schichten von Benutzeroberfläche, Geschäftslogik und Datenzugriff durchgeführt werden. Sie können dazu drei Tasks erstellen, die jeweils eine dieser drei Schichten betreffen, und sie dem jeweiligen Spezialisten zuweisen: dem WPF-Entwickler, dem C#-Experten und dem Datenbankguru. Wenn Sie Glück haben und ein Team von universellen Spezialisten am Werk ist, sollte sich für jeden Task im Idealfall ein Freiwilliger melden. So kann jeder an unterschiedlichen Codeteilen arbeiten, was nicht nur Eintönigkeit vermeidet, sondern auch bewirkt, dass die Mitarbeiter die Software besser kennen.

Der vertikale Schnitt

Als ich klein war, backte mein Vater an Weihnachten immer einen Trifle. Das ist eine traditionelle englische Nachspeise, die aus mehreren Schichten besteht. Ganz unten beginnt sie mit aufgeschnittenen Früchten, dann folgen Biskuit, Marmelade und Creme, den krönenden Abschluss bildet Schlagsahne. Mein Bruder grub sich mit seinem Löffel durch alle Schichten nach unten durch, während ich nacheinander jede Schicht vollständig verputzte, bevor ich zur nächsten vorrückte.

Gut entworfene Software besteht aus Schichten, genau wie ein Trifle. Die unterste Schicht befasst sich mit dem Datenzugriff, gefolgt von Schichten für objektrelationale Abbildung, Domänenmodelle, Dienste und Controller, ganz oben kommt schließlich die Benutzeroberfläche. Und wie beim Essen von Trifle gibt es zwei unterschiedliche Methoden, ein Stück von einer mehrschichtigen Anwendung abzuschneiden: vertikal und horizontal.

Wenn Sie horizontal schneiden, nehmen Sie jede Schicht und implementieren alle erforderlichen Elemente der jeweiligen Schicht. Dabei ist aber nicht garantiert, dass die Stücke jederzeit zueinander passen. Vielleicht ermöglicht die Benutzeroberfläche dem Benutzer schon, bestimmte Features zu verwenden, die in den niedrigeren Schichten noch gar nicht implementiert wurden. Folglich kann der Kunde die Anwendung erst nutzen, wenn große Teile jeder Schicht fertig sind. Das verzögert die wichtige Feedbackschleife, auf die agile Methoden großen Wert legen, und es erhöht die Gefahr, dass Sie mehr entwickeln, als tatsächlich gebraucht wird – oder einfach etwas völlig Falsches.

Sie sollten daher nach einem vertikalen Schnitt streben. Jede User Story sollte Funktionen aus allen Schichten umfassen und ganz oben in der Benutzeroberfläche verankert sein. Auf diese Weise können Sie dem Benutzer die Funktion demonstrieren und erhalten bald Feedback. Außerdem wird dadurch verhindert, dass User Stories aus Entwicklersicht verfasst werden, zum Beispiel »Ich will aus der Datenbank eine Liste aller Kunden abrufen, die diesen Monat nicht bezahlt haben.« Das klingt zu sehr nach einem Task. Eine Story würde sich damit befassen, einen Bericht über Kundenkonten zu generieren, die Zahlungsrückstände haben.

Es ist wichtig, dass Story-Punkte den User Stories zugeordnet sind, und dass die Story-Punkte nicht auf die untergeordneten Tasks verteilt werden dürfen. Eine 5-Punkt-Story, die in drei Einzeltasks untergliedert wird, besteht nicht aus zwei 1-Punkt-Tasks und einem 3-Punkt-Task. Es sollen keine Anreize geschaffen werden, unfertige Arbeit abzuliefern. Die Punkte einer Story werden nur zugeteilt, wenn die Story am Ende des Sprints im Rahmen der Qualitätssicherung als vollständig bestätigt wurde. Vorher gibt es keine »Anzahlung«. Fehlt die Bestätigung der Qualitätssicherung, bleibt die Story bis zum nächsten Sprint in Arbeit, wo sie dann hoffentlich bald innerhalb der Iteration abgeschlossen wird. Dauert es zu lange, eine Story abzuschließen, sodass sie lange Zeit in Arbeit bleibt (mehr als die volle Länge eines Sprints), war sie wahrscheinlich von Anfang an zu umfangreich und hätte in kleinere, handlichere Stories unterteilt werden sollen.

Technical Debt

Technical Debt (technische Schulden) ist ein sehr interessantes Konzept, das leider oft missverstanden wird. Technical Debt ist eine Metapher für die Kompromisse, die bei Entwurf und Architektur eingegangen wurden, während eine Story sich über das Scrum-Board bewegt. Technical Debt wird weiter unten in diesem Kapitel in einem eigenen Abschnitt genauer beschrieben.

Defekt

Eine Defektkarte (engl. defect card) wird immer dann erstellt, wenn die Akzeptanzkriterien einer früher bereits abgeschlossenen User Story nicht mehr erfüllt sind. Das macht deutlich, warum automatisierte Akzeptanztests gebraucht werden: Jede Gruppe von Tests, die für eine Story geschrieben werden, bildet eine Familie von Regressionstests, die sicherstellen, dass spätere Arbeiten keine Veränderungen einführen, die eine ältere User Story beschädigen.

Wie Technical-Debt-Karten sind auch Defektkarten keine Story-Punkte zugewiesen. Daher gibt es keine Motivation, Defekte und Technical Debt zu erzeugen – was Entwickler ohnehin immer zu vermeiden suchen, selbst wenn es niemals möglich ist, alle Defekte und jegliche Technical Debt zu beseitigen.

Jede Software enthält Fehler. Das ist eine unumstößliche Tatsache in der Softwareentwicklung. Auch mit noch so viel Planung und Sorgfalt lassen sich niemals alle menschlichen Fehlerquellen ausschalten. Defekte können grob in die Kategorien A, B oder C eingeteilt werden: apokalyptische Defekte (engl. Apocalyptic, A), Verhaltens-Fehler (engl. Behavioral, B) und kosmetische Probleme (engl. Cosmetic, C).

Apokalyptische Defekte lassen die Anwendung abstürzen oder verhindern, dass der Benutzer weiterarbeiten kann. Das klassische Beispiel ist eine nicht abgefangene Ausnahme, weil das Programm daraufhin beendet und neu gestartet oder (bei einer Webanwendung) die Webseite neu geladen werden muss. Diesen Defekten sollte die höchste Priorität zugewiesen werden, und sie sollten vor einem Release der Software beseitigt werden.

Verhaltensfehler sind meist nicht ganz so tragisch, können die Benutzer aber zur Weißglut treiben. Solche Fehler können sogar mehr Schaden verursachen als eine Anwendung, die schlicht abstürzt. Stellen Sie sich vor, dass eine Währungsumrechnungslogik die Daten falsch rundet. Unabhängig davon, ob der Algorithmus Vorteile für den Kunden oder das Unternehmen bringt, verliert jemand Geld. Natürlich sind nicht alle Logikfehler so folgenschwer, aber an diesem Beispiel ist deutlich zu sehen, warum solche Fehler mittlere bis hohe Priorität erhalten sollten.

Kosmetische Probleme betreffen meist die Benutzeroberfläche: seltsam verschobene Abbildungen, ein Fenster, das sich nicht sinnvoll vergrößern lässt oder ein Bild auf einer Webseite, das niemals geladen wird. Solche Probleme schränken nicht den Nutzen der Software ein, sondern nur ihr Aussehen. Auch wenn diese Probleme meist eine niedrigere Priorität erhalten, dürfen Sie nicht vergessen, dass das Aussehen großen Einfluss auf die Erwartungen des Benutzers an die Software hat. Ist die Benutzeroberfläche schlecht entworfen, mit Schaltflächen, die nicht funktionieren, und Bildern, die nicht geladen werden, sinkt das Vertrauen der Benutzer in die internen Vorgänge dieser Software. Umgekehrt vermittelt eine schicke Benutzeroberfläche mit tollem Design den Benutzern den Eindruck, dass Ihre Software auch intern solide entworfen ist. Projekte, die sich einen schlechten Ruf erworben haben, greifen oft zu dem Trick, die Benutzeroberfläche zu überarbeiten (und vielleicht das gesamte Produkt umzutaufen), um mit der Vergangenheit zu brechen und das beschädigte Renommee abzuschütteln.

Kartentricks

Es gibt eine Menge Möglichkeiten, die Karten auf dem Scrum-Board an persönliche Vorlieben anzupassen.

Farbschema

Für die Karten tut es jedes beliebige Farbschema, aber ich habe die Erfahrung gemacht, dass bestimmte Farben am sinnvollsten sind. Karteikarten eignen sich ideal für Features und User Stories, während Haftnotizen perfekte Karten für Task, Defekt und Technical Debt sind, weil sie dann an eine bestimmte Story geklebt werden können. Hier meine Empfehlungen:

Features: grüne Karteikarten

User Stories: weiße Karteikarten

Tasks: gelbe Haftnotizen

Defekte: rote/rosa Haftnotizen

Technical Debt: lila/blaue Haftnotizen

Am häufigsten werden Sie Karten für User Stories und Tasks erstellen, daher sollten Sie dafür jederzeit verfügbare Karteikarten und Haftnotizen einsetzen. Sie sollten wirklich nicht daran scheitern, dass Ihnen die Karteikarten ausgehen, daher sollten Sie sich an überall erhältliche Farben halten.

Wer fertigt die Karten an?

Auf die Frage »Wer darf Karten anfertigen?« gibt es eine simple Antwort: jeder. Daran sind natürlich einige Bedingungen geknüpft. Auch wenn jeder eine Karte anfertigen darf, sollten ihre Gültigkeit, Priorität, Wichtigkeit und andere Eigenschaften nicht von einer Person allein festgelegt werden. Alle Feature- und Story-Karten sollten vom Product Owner überprüft werden. Für Task-, Defekt- und Technical-Debt-Karten ist dagegen allein das Entwicklungsteam verantwortlich.

Avatare