9 783864 902857 Gary McLean Hall Gary MacLean Hall 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 Unter »Microsoft Press« erscheinen exklusiv im dpunkt.verlag Übersetzungen der besten Microsoft PressTitel. Thema • Softwareentwicklung • C# Leser • fortgeschrittene Programmierer Website • http://github.com/ garymclean/ AdaptiveCode € 39,90(D) € 41,10 (A) ISBN 978-3-86490-285-7 www.dpunkt.de Interesse am E-Book? www.dpunkt.de/plus McLean Hall Wie geht man am besten mit wechselnden Anforderungen im Laufe eines Software projektes 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. Agile Softwareentwicklung mit C# Agile Softwareentwicklung mit C# Agile Softwareentwicklung mit C# Best Practices und Patterns für flexiblen und adaptiven C#-Code 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 Gary McLean Hall Agile Softwareentwicklung mit C# Best Practices und Patterns für flexiblen und adaptiven C#-Code Gary McLean Hall Übersetzung: Detlef Johannis, Kempten Lektorat: Thomas Braun-Wiesholler, München Copy-Editing: Dorothee Klein, Siegen Herstellung: Frank Heidt Satz: Gerhard Alfes, mediaService, Siegen, www.mediaservice.tv Umschlaggestaltung: Helmut Kraus, www.exclam.de Druck und Bindung: M.P. Mediaprint Informationsdienste, Paderborn Bibliografische Information der Deutschen Nationalbibliothek Die Deutsche Nationalbibliothek verzeichnet diese Publikation in der Deutschen Nationalbibliografie; detaillierte bibliografische Daten sind im Internet über http://dnb.d-nb.de abrufbar. ISBN: Buch PDF ePub 978-3-86490-285-7 978-3-86491-690-8 978-3-86491-691-5 Translation Copyright für die deutschsprachige Ausgabe © 2015 dpunkt.verlag GmbH Wieblinger Weg 17 69123 Heidelberg Copyright der amerikanischen Originalausgabe © Gary McLean Hall, 2014 Title of American original: Adaptive Code via C# Published by Microsoft Press ISBN: 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. 543210 Für Amelia Rose – Gary McLean Hall Inhaltsübersicht Einführung 1 TEIL I Eine agile Grundlage Kapitel 1 Einführung in Scrum 13 Kapitel 2 Abhängigkeiten und Schichten 57 Kapitel 3 Schnittstellen und Entwurfs-Patterns 111 Kapitel 4 Unit-Tests und Refaktorierung 147 TEIL II Schreiben von SOLID-Code Kapitel 5 Das Single-Responsibility-Prinzip Kapitel 6 Das Open/Closed-Prinzip 237 Kapitel 7 Das Liskovsche Substitutionsprinzip 247 Kapitel 8 Interface-Segregation 283 Kapitel 9 Dependency-Injection 317 TEIL III Entwickeln von adaptivem Code in der Praxis Kapitel 10 Beispiel für die Entwicklung von adaptivem Code: Einführung 365 Kapitel 11 Beispiel für die Entwicklung von adaptivem Code: Sprint 1 379 Kapitel 12 Beispiel für die Entwicklung von adaptivem Code: Sprint 2 409 TEIL IV Anhang Anhang A Adaptive Tools Anhang B GitHub-Codebeispiele Stichwortverzeichnis 195 427 online 435 vii Inhaltsverzeichnis Einführung 1 Wer sollte dieses Buch lesen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 Aufbau dieses Buchs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 Konventionen in diesem Buch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 Systemvoraussetzungen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 Downloads: Codebeispiele . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 Danksagungen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 Errata und Support . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 Kostenlose E-Books von Microsoft Press . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 TEIL I Eine agile Grundlage Kapitel 1 Einführung in Scrum 13 Scrum und Wasserfall . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 Rollen und Verantwortungsbereiche . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 Product Owner . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Scrum Master . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Entwicklungsteam . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Schweine und Hühner . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 19 19 20 Artefakte . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 Das Scrum-Board . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Diagramme und Kennzahlen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Backlogs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 35 40 Der Sprint . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42 Releaseplanung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Sprintplanung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Daily Scrum . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Sprintvorführung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Sprint-Retrospektive . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Scrum-Kalender . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43 43 45 47 48 50 Probleme beim Einsatz von Scrum und Agile . . . . . . . . . . . . . . . . . . . . . . . . . . . 51 Nicht adaptiver Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52 Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56 ix Kapitel 2 Kapitel 3 Kapitel 4 x Abhängigkeiten und Schichten 57 Die Definition von Abhängigkeit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58 Ein simples Beispiel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Modellieren von Abhängigkeiten in einem gerichteten Graphen . . . . . . . 59 66 Verwalten von Abhängigkeiten . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70 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 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71 71 75 78 80 82 93 Schichten . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98 Wichtige Patterns . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Grenzüberschreitende Angelegenheiten . . . . . . . . . . . . . . . . . . . . . . . . . . . . Asymmetrische Schichteinteilung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99 106 107 Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110 Schnittstellen und Entwurfs-Patterns 111 Was ist eine Schnittstelle? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112 Syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Explizite Implementierung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Polymorphie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112 115 120 Adaptive Entwurfs-Patterns . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121 Das Null-Object-Pattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Das Adapter-Pattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Das Strategy-Pattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122 128 131 Mehr Vielseitigkeit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132 Duck-Typing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Mixins . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Flüssige Schnittstellen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133 137 143 Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144 Unit-Tests und Refaktorierung 147 Unit-Tests . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148 Arrange, Act, Assert . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Testorientierte Entwicklung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Komplexere Tests . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148 153 158 Inhaltsverzeichnis Refaktorieren . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 175 Vorhandenen Code ändern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 175 Ein neuer Kontotyp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185 Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 190 TEIL II Schreiben von SOLID-Code Kapitel 5 Das Single-Responsibility-Prinzip 195 Das Problem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 196 Refaktorieren, um die Übersichtlichkeit zu verbessern . . . . . . . . . . . . . . . . . 199 Refaktorieren, um Abstraktion zu erreichen . . . . . . . . . . . . . . . . . . . . . . . . . . 204 SRP und das Decorator-Pattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212 Das Composite-Pattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Predicate-Decorator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Branching-Decorator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Lazy-Decorator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Logging-Decorator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Profiling-Decorator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Asynchronous-Decorator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Decorator für Eigenschaften und Ereignisse . . . . . . . . . . . . . . . . . . . . . . . . . 213 218 221 222 223 225 229 231 Verwenden des Strategy-Patterns statt switch . . . . . . . . . . . . . . . . . . . . . . . . . . 233 Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 235 Kapitel 6 Das Open/Closed-Prinzip 237 Einführung in das Open/Closed-Prinzip . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 237 Die Meyer-Definition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Die Martin-Definition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Fehlerkorrekturen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Lose Kopplung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 237 238 238 239 Erweiterungspunkte . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 239 Code ohne Erweiterungspunkte . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Virtuelle Methoden . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Abstrakte Methoden . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Schnittstellenvererbung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Vererbung in den Entwurf einarbeiten . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 240 240 241 242 243 Geschützte Variation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 244 Prognostizierte Variation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 244 Eine stabile Schnittstelle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 245 Gerade genug Anpassungsfähigkeit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 245 Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 246 Inhaltsverzeichnis xi Kapitel 7 Kapitel 8 Kapitel 9 xii Das Liskovsche Substitutionsprinzip 247 Einführung in das Liskovsche Substitutionsprinzip . . . . . . . . . . . . . . . . . . . . . . 247 Formale Definition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . LSP-Regeln . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 248 248 Verträge . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 249 Vorbedingungen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Nachbedingungen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Dateninvarianten . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Liskovsche Vertragsregeln . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Codeverträge . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 251 252 253 255 263 Kovarianz und Kontravarianz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 271 Definitionen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Liskovsche Typsystemregeln . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 271 278 Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 281 Interface-Segregation 283 Ein Beispiel für Interface-Segregation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 284 Eine einfache CRUD-Schnittstelle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Caching . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Dekorieren mehrerer Schnittstellen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 284 290 294 Verwenden von Schnittstellen in Clients . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 297 Mehrere Implementierungen, mehrere Instanzen . . . . . . . . . . . . . . . . . . . . Einzelne Implementierung, einzelne Instanz . . . . . . . . . . . . . . . . . . . . . . . . . Das Interface-Soup-Anti-Pattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 297 300 301 Zerlegen von Schnittstellen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 302 Anforderungen des Clients . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Anforderungen der Architektur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Schnittstellen mit einer einzigen Methode . . . . . . . . . . . . . . . . . . . . . . . . . . 302 309 313 Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 315 Dependency-Injection 317 Bescheidene Anfänge . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 318 Die Aufgabenlistenanwendung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Erstellen des Objektgraphen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Inversion of Control . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 321 324 328 Inhaltsverzeichnis Jenseits der simplen Injection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 344 Das Service-Locator-Anti-Pattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Das Illegitimate-Injection-Anti-Pattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Die Composition-Root . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Konvention vor Konfiguration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 344 348 350 356 Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 361 TEIL III Entwickeln von adaptivem Code in der Praxis Kapitel 10 Beispiel für die Entwicklung von adaptivem Code: Einführung 365 Trey Research . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 365 Das Team . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 366 Das Produkt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 369 Anfängliches Backlog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 369 User Stories in Prosabeschreibungen finden . . . . . . . . . . . . . . . . . . . . . . . . . 370 Abschätzen der Story-Punkte . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 372 Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 377 Kapitel 11 Beispiel für die Entwicklung von adaptivem Code: Sprint 1 379 Planung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 379 »Ich will Räume anlegen, um Unterhaltungen thematisch einzugrenzen.« . . 382 Der Controller . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 382 Das Raum-Repository . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 387 »Ich will eine Liste der Räume ansehen, die Unterhaltungen repräsentieren.« 392 »Ich will die Nachrichten ansehen, die an einen Raum geschickt wurden.« . 397 »Ich will reine Textnachrichten an andere Raummitglieder schicken.« . . . . . . 400 Sprintvorführung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 401 Erste Vorführung von Proseware . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 402 Sprint-Retrospektive . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 403 Was lief gut? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Was lief schlecht? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Was sollte sich ändern? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Was sollte beibehalten werden? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Überraschungen? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 403 404 405 406 407 Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 408 Inhaltsverzeichnis xiii Kapitel 12 Beispiel für die Entwicklung von adaptivem Code: Sprint 2 409 Planung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 409 »Ich will Markdown senden, der richtig formatiert ist.« . . . . . . . . . . . . . . . . . . 411 »Ich will Nachrichteninhalte so filtern, dass sie nicht anstößig sind.« . . . . . . 415 »Ich will Hunderte von Benutzern gleichzeitig bedienen.« . . . . . . . . . . . . . . . 419 Sprintvorführung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 421 Sprint-Retrospektive . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 422 Was lief gut? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Was lief schlecht? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Was sollte sich ändern? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Was sollte beibehalten werden? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Überraschungen? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 422 423 423 424 424 Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 424 TEIL IV Anhang Anhang A Adaptive Tools 427 Quellcodeverwaltung mit Git . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 427 Kontinuierliche Integration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 432 Anhang B GitHub-Codebeispiele Stichwortverzeichnis xiv Inhaltsverzeichnis online 435 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 1
© Copyright 2025 ExpyDoc